Вот пример использования контроллера, введенного Guice.
/**
* Loads a FXML file and injects its controller from the given Guice {@code Provider}
*/
public abstract class GuiceFxmlLoader {
public GuiceFxmlLoader(Stage stage, Provider<?> provider) {
mStage = Objects.requireNonNull(stage);
mProvider = Objects.requireNonNull(provider);
}
/**
* @return the FXML file name
*/
public abstract String getFileName();
/**
* Load FXML, set its controller with given {@code Provider}, and add it to {@code Stage}.
*/
public void loadView() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource(getFileName()));
loader.setControllerFactory(p -> mProvider.get());
Node view = loader.load();
setViewInStage(view);
}
catch (IOException ex) {
LOGGER.error("Failed to load FXML: " + getFileName(), ex);
}
}
private void setViewInStage(Node view) {
BorderPane pane = (BorderPane)mStage.getScene().getRoot();
pane.setCenter(view);
}
private static final Logger LOGGER = Logger.getLogger(GuiceFxmlLoader.class);
private final Stage mStage;
private final Provider<?> mProvider;
}
Вот конкретная реализация загрузчика:
public class ConcreteViewLoader extends GuiceFxmlLoader {
@Inject
public ConcreteViewLoader(Stage stage, Provider<MyController> provider) {
super(stage, provider);
}
@Override
public String getFileName() {
return "my_view.fxml";
}
}
Обратите внимание, что этот пример загружает представление в центр BoarderPane, который является корнем сцены в рабочей области. Это не относится к примеру (деталь реализации моего конкретного варианта использования), но решил оставить его, поскольку некоторые из них могут оказаться полезными.
Поскольку из комментариев, опубликованных OP, кажется, что он не хочет сохранять «абсолютные URL-адреса» в соединении (что является одной из ключевых задач urlparse.urljoin
;-), я бы рекомендовал избегать этого. os.path.join
тоже будет плохим по той же причине.
Итак, я бы использовал что-то вроде '/'. Join (s.strip ('/') для s в кусках)
(если ведущая часть /
также должна быть проигнорирована - если ведущая часть должна быть в особом регистре, это, конечно, также возможно; -).
Я нашел вещи не любить приблизительно все вышеупомянутые решения, таким образом, я придумал свое собственное. Эта версия удостоверяется, что к частям присоединяются с единственной наклонной чертой, и оставляет ведущие и запаздывающие наклонные черты в покое. Никакой pip install
, никакой urllib.parse.urljoin
странность.
In [1]: from functools import reduce
In [2]: def join_slash(a, b):
...: return a.rstrip('/') + '/' + b.lstrip('/')
...:
In [3]: def urljoin(*args):
...: return reduce(join_slash, args) if args else ''
...:
In [4]: parts = ['https://foo-bar.quux.net', '/foo', 'bar', '/bat/', '/quux/']
In [5]: urljoin(*parts)
Out[5]: 'https://foo-bar.quux.net/foo/bar/bat/quux/'
In [6]: urljoin('https://quux.com/', '/path', 'to/file///', '//here/')
Out[6]: 'https://quux.com/path/to/file/here/'
In [7]: urljoin()
Out[7]: ''
In [8]: urljoin('//','beware', 'of/this///')
Out[8]: '/beware/of/this///'
In [9]: urljoin('/leading', 'and/', '/trailing/', 'slash/')
Out[9]: '/leading/and/trailing/slash/'
Python2
>>> import urlparse
>>> urlparse.urljoin('/media/path/', 'js/foo.js')
'/media/path/js/foo.js'
Но будьте осторожны ,
>>> import urlparse
>>> urlparse.urljoin('/media/path', 'js/foo.js')
'/media/js/foo.js'
, а также
>>> import urlparse
>>> urlparse.urljoin('/media/path', '/js/foo.js')
'/js/foo.js'
Python3
>>> import urllib.parse
>>> urllib.parse.urljoin('/media/path/', 'js/foo.js')
'/media/path/js/foo.js'
Причина, по которой вы получаете разные результаты из /js/foo.js
и js / foo.js
потому, что первый начинается с косой черты, что означает, что он уже начинается в корне веб-сайта.
Функция basejoin в пакете urllib может быть тем, что вы ищете.
basejoin = urljoin(base, url, allow_fragments=True)
Join a base URL and a possibly relative URL to form an absolute
interpretation of the latter.
Edit: Я не замечал раньше, но urllib.basejoin, похоже, напрямую сопоставляется с urlparse.urljoin, что делает последний предпочтительным.