-3

I have problem with opening file from table in my JavaFX app. When user click on the row, new window should open because in the table I have path to specialty file for example:

1  document  C:/Users/document.docx

After user click on this row new office window will open. Below I add my code:

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());
                    }
                }
            }
    });
}
mroma95
  • 97
  • 12
  • Surely just `String[] selectedRow = contentTable.getSelectionModel().getSelectedItem();` and then the path you want is some element of that array (if it's not null). – James_D Mar 23 '21 at 13:21

1 Answers1

1

Note that class Desktop belongs to AWT and according to this other stackoverflow question – Is it OK to use AWT with JavaFx? – it is not recommended to mix the two. There is also an open bug: JDK-8240572

I propose two alternatives.

  1. If you want to use JavaFX then launch the file using class ProcessBuilder rather than class Desktop. Here is sample code. (Note that I am on 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 can be used with Swing so you can use class Desktop if you are willing to use Swing rather than JavaFX. Here is sample code.
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());
    }
}

Note that both the above code samples use method references.

Abra
  • 19,142
  • 7
  • 29
  • 41