【问题标题】:Open file from table JavaFX [closed]从表 JavaFX 打开文件 [关闭]
【发布时间】:2021-06-20 00:45:35
【问题描述】:

在我的 JavaFX 应用程序中从表中打开文件时遇到问题。当用户单击该行时,应该会打开新窗口,因为在表格中我有专业文件的路径,例如:

1  document  C:/Users/document.docx

用户点击此行后,将打开新的办公窗口。下面我添加我的代码:

private void configureTableClick() {
    TableView<String[]> contentTable = contentPaneController.getContentTable();
    contentTable.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEvent -> {
            if (mouseEvent.getClickCount() == 1) {
                int selectedIndex = contentTable.getSelectionModel().getSelectedIndex();
                String fileToOpen;
                if (selectedIndex > 0) {
                    try {
                        Desktop.getDesktop().open(new File(fileToOpen));
                    } catch (IOException e) {
                        log.error(e.getMessage());
                    }
                }
            }
    });
}

【问题讨论】:

  • 当然只是String[] selectedRow = contentTable.getSelectionModel().getSelectedItem();,然后您想要的路径是该数组的某个元素(如果它不为空)。

标签: java user-interface javafx


【解决方案1】:

请注意,Desktop 类属于 AWT,根据另一个 stackoverflow 问题 - Is it OK to use AWT with JavaFx? - 不建议将两者混合使用。还有一个开放的bug:JDK-8240572

我提出了两种选择。

  1. 如果您想使用 JavaFX,请使用 ProcessBuilder 类而不是 Desktop 类启动文件。这是示例代码。 (请注意,我使用的是 Windows 10。)
import java.io.IOException;

import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.SelectionModel;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TableTst extends Application {
    private TableView<FileObj>  table;

    @Override
    public void start(Stage primaryStage) throws Exception {
        FileObj row = new FileObj(1, "document", "C:/Users/document.docx");
        ObservableList<FileObj> items = FXCollections.observableArrayList(row);
        table = new TableView<>(items);
        TableColumn<FileObj, Number> indexColumn = new TableColumn<>("Index");
        indexColumn.setCellValueFactory(param -> param.getValue().indexProperty());
        table.getColumns().add(indexColumn);
        TableColumn<FileObj, String> typeColumn = new TableColumn<>("Type");
        typeColumn.setCellValueFactory(param -> param.getValue().fileTypeProperty());
        table.getColumns().add(typeColumn);
        TableColumn<FileObj, String> pathColumn = new TableColumn<>("Path");
        pathColumn.setCellValueFactory(param -> param.getValue().filePathProperty());
        table.getColumns().add(pathColumn);
        SelectionModel<FileObj> tableSelectionModel = table.getSelectionModel();
        tableSelectionModel.selectedItemProperty().addListener(this::handleTableSelection);
        BorderPane root = new BorderPane(table);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void handleTableSelection(ObservableValue<? extends FileObj> property,
                                      FileObj oldValue,
                                      FileObj newValue) {
        if (newValue != null) {
            String path = newValue.getFilePath();
            ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", path);
            try {
                Process p = pb.start();
                p.waitFor();
            }
            catch (InterruptedException | IOException x) {
                x.printStackTrace();
            }
        }
    }

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

class FileObj {
    private SimpleIntegerProperty  index;
    private SimpleStringProperty  fileType;
    private SimpleStringProperty  filePath;

    public FileObj(int ndx, String type, String path) {
        index = new SimpleIntegerProperty(this, "index", ndx);
        fileType = new SimpleStringProperty(this, "fileType", type);
        filePath = new SimpleStringProperty(this, "filePath", path);
    }

    public int getIndex() {
        return index.get();
    }

    public SimpleIntegerProperty indexProperty() {
        return index;
    }

    public String getFileType() {
        return fileType.get();
    }

    public SimpleStringProperty fileTypeProperty() {
        return fileType;
    }

    public String getFilePath() {
        return filePath.get();
    }

    public SimpleStringProperty filePathProperty() {
        return filePath;
    }
}
  1. AWT 可以与 Swing 一起使用,因此如果您愿意使用 Swing 而不是 JavaFX,则可以使用 Desktop 类。这是示例代码。
import java.awt.Desktop;
import java.awt.EventQueue;
import java.io.File;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;

public class TesTable {
    private JFrame  frame;
    private JTable  table;

    private JScrollPane createTable() {
        String[] columns = new String[]{"Index", "Type", "Path"};
        String[][] data = new String[][]{{"1", "document", "C:/Users/document.docx"}};
        table = new JTable(data, columns);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.getSelectionModel().addListSelectionListener(this::handleTableSelection);
        JScrollPane scrollPane = new JScrollPane(table);
        return scrollPane;
    }

    private void showGui() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createTable());
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void handleTableSelection(ListSelectionEvent event) {
        if (Desktop.isDesktopSupported()) {
            Desktop desktop = Desktop.getDesktop();
            int ndx = event.getFirstIndex();
            if (ndx >= 0) {
                String path = (String) table.getValueAt(ndx, 2);
                File f = new File(path);
                try {
                    desktop.open(f);
                }
                catch (IOException xIo) {
                    xIo.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        final TesTable instance = new TesTable();
        EventQueue.invokeLater(() -> instance.showGui());
    }
}

请注意,以上两个代码示例都使用method references

【讨论】:

  • 在 JavaFX 中,我认为 getHostServices().showDocument(...) 也可以。
猜你喜欢
  • 2015-02-14
  • 2019-03-07
  • 2017-05-26
  • 2015-01-11
  • 1970-01-01
  • 2012-10-01
  • 2016-06-26
  • 2019-04-14
  • 1970-01-01
相关资源
最近更新 更多