I am developing an application in which I have some links added to the Listview and these links will keep on adding at runtime on some condition.So what I can\'t find is a w
Old question, old answer which is working fine - but has a slight smell: it's adding views (Hyperlinks) as data to the ListView.
The cleaner alternative is to add URLs as data and implement a custom cell that uses Hyperlinks to show (and allow interaction with) the URLs.
A quick code example:
final ListView<URL> listView = new ListView<>();
@Override
public void start(Stage primaryStage) throws MalformedURLException {
ObservableList<URL> urls = FXCollections.observableArrayList(
new URL("http://blog.professional-webworkx.de"),
new URL("http://www.stackoverflow.com")
);
listView.getItems().addAll(urls);
listView.setCellFactory(c -> {
ListCell<URL> 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;
});
// ...
}
I put a Tooltip to the hyperlink and read the url from there, and seems to work. i.e.:
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();
});
I made a very small example Application for you,
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<Hyperlink> 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<ActionEvent>() {
@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<ActionEvent>() {
@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<ActionEvent>() {
@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);
}
}
If you enter a new URL in the TextField and click on the Button, the new Link will be added to your LinkList and will be displayed on the ListView. Everytime you add a new Link, the .setOnAction()
Method is set with the right URL to open.
Maybe you can use this as starting point for further developing your app.
Patrick