When click on Hyperlink in JavaFX, a relevant URL should open in browser
Asked Answered
Z

3

5

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. What I can't find is a way to to open a url when clicking on a particular link.

This is the code for adding links into list view

if (counter == 1) {
    Task task2 = new Task<Void>() {
        @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);
}

I know I need to use something like this to open a url in browser when click on link:

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

I don't know how to listen/track the click event for different links.

Zink answered 27/6, 2014 at 9:7 Comment(1)
This related example uses the approach illustrated in this recent answer.Lordling
A
11

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

Abbreviation answered 27/6, 2014 at 11:43 Comment(4)
Thanks for your help Patrick.I will try to apply it in my logic :)Zink
@AnishSharma No problem, come back with a bit more code, often you'll read on SO that you should post an MCVE to get help faster.Abbreviation
No, it does not! But I have managed to get it around. It's a bit lengthy solution but serving the purpose.Focalize
getHostServices is my learn item of the day :) Nitpicking: you wouldn't add hyperlinks to the list - instead, have list of urls as data and a custom cell factory the uses hyperlinks to show the urls and trigger the opening of the url as neededMontero
F
5

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();
});
Federalist answered 24/4, 2016 at 10:26 Comment(0)
M
3

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;
    });
   // ... 
}
Montero answered 9/10, 2018 at 11:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.