javafx:在表格单元格中显示超链接

时间:2018-05-31 10:57:19

标签: javafx

我是JAVAFX的新手,正在尝试在表格单元格中显示超链接。我可以显示为超链接但无法打开链接。

请找到相同的逻辑。

主要方法在这里::

 public class Main extends Application {
    private BorderPane root;
    private TableView<Item> table;
    private Scene scene;
    private TableColumn<Item, String> nameColumn;
    private TableColumn<Item, Hyperlink> urlColumn;
    private ObservableList<Item> websiteList;


@Override
public void start(Stage primaryStage) {

    root = new BorderPane();
    //scene = new Scene(root, 400, 400);

    table = new TableView<Item>();

    //root.setCenter(table);
    nameColumn = new TableColumn<>("Name");

    nameColumn.setCellValueFactory(new PropertyValueFactory<>("websiteName"));

    urlColumn = new TableColumn<>("Address");
    urlColumn.setCellValueFactory(new PropertyValueFactory<>("hyperlink"));
    urlColumn.setCellFactory(new HyperlinkCell());

    table.getColumns().add(nameColumn);
    table.getColumns().add(urlColumn);
    websiteList = FXCollections.observableArrayList();
    websiteList.add(new Item("Google", "https://www.google.co.in/"));
    websiteList.add(new Item("Facebook", "www.facebook.com"));
    websiteList.add(new Item("Superglobals", "www.superglobals.net"));

    Hyperlink hyperlink = new Hyperlink("Go to Eclipse home page");

    hyperlink.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            getHostServices().showDocument("https://www.google.co.in/");
        }
    });
    root.getChildren().addAll(hyperlink);
   // root.setBottom(hyperlink);
    table.setItems(websiteList);
    root.setCenter(table);
    scene = new Scene(root, 400, 400);
    primaryStage.setScene(scene);
    primaryStage.show();
}

public static void main(String[] args) {
    launch(args);
}

}

Item.java ::

public class Item {
    private String websiteName;
    private Hyperlink hyperlink;

    public Item(String websiteName, String websiteUrl) {
        this.websiteName = websiteName;
        this.hyperlink = new Hyperlink(websiteUrl);
    }

    public String getWebsiteName() {
        return websiteName;
    }

    public void setWebsiteName(String websiteName) {
        this.websiteName = websiteName;
    }

    public Hyperlink getHyperlink() {
        return hyperlink;
    }

    public void setHyperlink(String websiteUrl) {
        this.hyperlink = new Hyperlink(websiteUrl);
    }
}

HyperlinkCell.java ::

public class HyperlinkCell implements  Callback<TableColumn<Item, Hyperlink>, TableCell<Item, Hyperlink>> {
 private static HostServices hostServices ;

    public static HostServices getHostServices() {
        return hostServices ;
    }
@Override
public TableCell<Item, Hyperlink> call(TableColumn<Item, Hyperlink> arg) {
    TableCell<Item, Hyperlink> cell = new TableCell<Item, Hyperlink>() {
        @Override
        protected void updateItem(Hyperlink item, boolean empty) {
            super.updateItem(item, empty);
            setGraphic(empty ? null : item);
        }
    };
    return cell;
}

}

输出显示如下但无法打开超链接。请帮助我们。

enter image description here

感谢。

1 个答案:

答案 0 :(得分:3)

只需更新onAction方法中超链接的updateItem()处理程序:

TableCell<Item, Hyperlink> cell = new TableCell<Item, Hyperlink>() {
    @Override
    protected void updateItem(Hyperlink item, boolean empty) {
        super.updateItem(item, empty);
        setGraphic(empty ? null : item);
        if (! empty) {
            item.setOnAction(e -> {
                // handle event here...
            });
        }
    }
};

请注意,在数据类(例如Hyperlink)中使用UI元素(例如Item)并不是一个好主意。我建议你重构一下,以便Item只保存数据:

public class Item {
    private String websiteName;
    private String url;

    public Item(String websiteName, String websiteUrl) {
        this.websiteName = websiteName;
        this.url = websiteUrl;
    }

    public String getWebsiteName() {
        return websiteName;
    }

    public void setWebsiteName(String websiteName) {
        this.websiteName = websiteName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String websiteUrl) {
        this.url = websiteUrl;
    }
}

然后:

private TableColumn<Item, String> urlColumn;

// ...

urlColumn = new TableColumn<>("Address");
urlColumn.setCellValueFactory(new PropertyValueFactory<>("url"));
urlColumn.setCellFactory(new HyperlinkCell());

start()中的某个地方你需要做

HyperlinkCell.setHostServices(getHostServices());

最后在单元格中定义Hyperlink。这样,每个单元格只有一个Hyperlink个实例,而不是表格中每个项目一个。

public class HyperlinkCell implements  Callback<TableColumn<Item, Hyperlink>, TableCell<Item, Hyperlink>> {

    private static HostServices hostServices ;

    public static HostServices getHostServices() {
        return hostServices ;
    }

    public static void setHostServices(HostServices hostServices) {
        HyperlinkCell.hostServices = hostServices ;
    }

    @Override
    public TableCell<Item, String> call(TableColumn<Item, String> arg) {
        TableCell<Item, Hyperlink> cell = new TableCell<Item, Hyperlink>() {

            private final Hyperlink hyperlink = new Hyperlink();

            {
                hyperlink.setOnAction(event -> {
                    String url = getItem();
                    hostServices.showDocument(url);
                });
            }

            @Override
            protected void updateItem(String url, boolean empty) {
                super.updateItem(url, empty);
                if (empty) {
                    setGraphic(null);
                } else {
                    hyperlink.setText(url);
                    setGraphic(hyperlink);
                }
            }
        };
        return cell;
    }

}