单击JavaFX中的超链接时,应在浏览器中打开相关URL

我正在开发一个应用程序,其中我有一些链接添加到Listview,这些链接将继续在运行时添加某些条件。所以我找不到的是如何在单击特定链接时打开URL的方法。

这是将链接添加到列表视图的代码

if(counter==1) { Task task2 = new Task() { @Override public Void call() throws Exception { Platform.runLater(new Runnable() { public void run() { link=new Hyperlink(val); link.setStyle("-fx-border-style: none;"); items.add(link); listview.setItems(items); } }); return null; } }; Thread th = new Thread(task2); th.setDaemon(true); th.start(); Thread.sleep(1000); } 

我知道我需要使用这样的东西在点击链接时在浏览器中打开一个url

  getHostServices().showDocument(link.getText()); 

但我不知道如何监听/跟踪不同链接的点击事件

我为你做了一个很小的例子申请,

 import java.util.ArrayList; import java.util.List; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Hyperlink; import javafx.scene.control.ListView; import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class ListList extends Application { final ListView listView = new ListView(); @Override public void start(Stage primaryStage) { List links = new ArrayList<>(); AnchorPane pane = new AnchorPane(); VBox vBox = new VBox(); final Hyperlink link = new Hyperlink("http://blog.professional-webworkx.de"); Hyperlink link2= new Hyperlink("http://www.stackoverflow.com"); links.add(link); links.add(link2); for(final Hyperlink hyperlink : links) { hyperlink.setOnAction(new EventHandler() { @Override public void handle(ActionEvent t) { getHostServices().showDocument(hyperlink.getText()); } }); } listView.getItems().addAll(links); HBox hBox = new HBox(); final TextField urlField = new TextField(); Button b = new Button("Add Links"); hBox.getChildren().addAll(b, urlField); b.setOnAction(new EventHandler() { @Override public void handle(ActionEvent t) { addLink(urlField.getText().trim()); urlField.clear(); } }); vBox.getChildren().add(hBox); vBox.getChildren().add(listView); pane.getChildren().add(vBox); Scene scene = new Scene(pane, 800, 600); primaryStage.setTitle("Hello World!"); primaryStage.setScene(scene); primaryStage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } private void addLink(final String url) { final Hyperlink link = new Hyperlink(url); link.setOnAction(new EventHandler() { @Override public void handle(ActionEvent t) { getHostServices().showDocument(link.getText()); //openBrowser(link.getText()); } }); listView.getItems().add(link); } private void openBrowser(final String url) { getHostServices().showDocument(url); } } 

如果在TextField中输入新URL并单击Button,则新链接将添加到LinkList中,并将显示在ListView上。 每次添加新链接时, .setOnAction()设置.setOnAction()方法,并打开正确的URL。

也许您可以将此作为进一步开发应用程序的起点。

帕特里克

我把一个工具提示添加到超链接并从那里读取url,似乎工作。 即:

 Hyperlink hl = new Hyperlink(sometext); hl.setTooltip(new Tooltip(theurlhere); hl.setOnAction((ActionEvent event) -> { Hyperlink h = (Hyperlink) event.getTarget(); String s = h.getTooltip().getText(); getHostServices.showDocument(s); event.consume(); }); 

旧问题,旧答案工作正常 – 但有一点点气味:它将视图(超链接)作为数据添加到ListView。

更清晰的替代方法是将URL添加为数据并实现使用超链接显示(并允许与URL交互)的自定义单元格。

一个快速的代码示例:

 final ListView listView = new ListView<>(); @Override public void start(Stage primaryStage) throws MalformedURLException { ObservableList urls = FXCollections.observableArrayList( new URL("http://blog.professional-webworkx.de"), new URL("http://www.stackoverflow.com") ); listView.getItems().addAll(urls); listView.setCellFactory(c -> { ListCell cell = new ListCell<>() { private Hyperlink hyperlink; { hyperlink = new Hyperlink(); hyperlink.setOnAction(e -> { if (getItem() != null) { getHostServices().showDocument(getItem().toString()); } }); setContentDisplay(ContentDisplay.GRAPHIC_ONLY); } @Override protected void updateItem(URL item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { hyperlink.setText(item.toString()); setGraphic(hyperlink); } else { setGraphic(null); } } }; return cell; }); // ... }