有一个超链接。当点击我想在外部浏览器中打开一个链接。
网络上引用的常用方法似乎是:
final Hyperlink hyperlink = new Hyperlink("http://www.google.com");
hyperlink.setOnAction(t -> {
application.getHostServices().showDocument(hyperlink.getText());
});
但是我没有Application
的引用。链接是从Dialog打开的,Dialog是从Controller打开的,Controller是通过fxml文件打开的,因此获取对Application对象的引用将是非常痛苦的。
有人知道一个简单的方法来做到这一点吗?
干杯
4条答案
按热度按时间4bbkushb1#
**解决方案1:**通过应用向下传递对
HostServices
的引用。这可能与您预期的“相当痛苦”的方法相似。但基本上你会做这样的事情:
然后在
MainController
中:DialogController
看起来像:**方案二:**使用控制器工厂将主机服务推送到控制器。
这是上面的一个更干净的版本。不需要获取控制器并调用方法来初始化它们,而是通过
controllerFactory
配置它们的创建,并通过将HostServices
对象传递给控制器的构造函数来创建控制器,如果它有合适的构造函数:现在,在加载FXML时使用控制器工厂:
并定义你的控制器接受
HostServices
作为构造函数参数:当然
**解决方案3:**这是一个非常丑陋的解决方案,我强烈建议不要使用它。 我只是想包括它,这样我就可以表达出来,而不会冒犯其他人。将主机服务存储在静态字段中。
那你就做吧
任何你需要的地方。这里的一个问题是,对于需要访问主机服务的所有控制器,您引入了对应用程序类型的依赖性。
方案4定义一个singleton
HostServicesProvider
。这比解决方案3好,但仍然不是一个好的解决方案。现在你只需要
和
解决方案5使用依赖注入框架。这可能不适用于您当前的用例,但可能会给予您了解这些(相对简单的)框架有多强大。
例如,如果您使用的是afterburner.fx,则只需执行以下操作
在应用程序中使用
start()
或init()
方法,然后使用Spring的一个例子是here。
kyvafyod2#
如果你想打开一个url当你点击一个按钮在你的应用程序,你正在使用一个fxml控制器文件,那么你可以做以下...
首先,在主应用程序启动文件中获取指向HostServices对象的指针,并将其添加到您的舞台,例如...
然后在fxml控制器文件中从stage对象获取hostServices对象,然后执行showDocument()方法。
在我的contoller类中有一个方法,叫做getStage()...
oxf4rvwz3#
另一种方法是使用java.awt.Desktop
未测试(untested):
但是请注意,这将引入对AWT堆栈的依赖性。如果您使用完整的JRE,这可能不是问题,但如果您想要使用定制的JRE(Java SE 9和Jigsaw)或如果您想要在移动终端上运行应用程序(javafxports),则可能会成为问题。
support Desktop in JavaFX在未来有一个开放的问题。
bsxbgnwa4#
在寻求更可持续的解决方案时,可以考虑以下任何一种临时方法:
1.让类 extend
Application
,让它访问HostServices
的示例。它不会是父应用程序的示例,但可能足够了。1.让类 * 包含 * 一个
Application
,它可以从中获得HostServices
的示例。同样,它不会是父应用程序的示例。在这个完整的example中,控制器的早期version只是扩展了
Application
。同一控制器的后一个version实现了一个合适的接口,以实现here概述的第一个解决方案。最近的version使用控制器工厂来提供参考,如第二个解决方案所示,参见here。从概念上讲,
HostServices
对于每个Application
示例都应该是唯一的。这意味着singleton pattern,建议的here和第四个解决方案概述的here。实际上,HostServices
是final
,source委托给一个私有类,称为here,它引用应用程序。