JavaFX: Layout changing after loading file

poisn :

Following problem:

I have a GUI with a TableView to show some data.

My GUI

To avoid some issues when I'm loading a new file into the table I call a method that clears all data from the table (this event happens after I select a file from the FileChooser and before the data is displayed).

The problem is, after loading a file, the layout is changing.

After loading a file

I found out this happens because I'm clearing the TableView property but I don't know how to fix this and couldn't find a solution.

Runnable Example

public class GuiLayout extends Application {

    private Scene mainScene;
    private Stage mainStage;
    private Label filename;
    private VBox mainBox;

    private TableView tableView = new TableView();

    private FileChooser fileChooser;
    private Button save;
    private Button neu;
    private Button settings;
    private Button table;
    private Button row;
    private Button column;
    private Button date;

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

    @Override
    public void start(Stage primaryStage) throws Exception {

        initButton();

        mainStage = new Stage();
        filename = new Label("Nr. 100 - Test Data (Applikation: TEST)");
        mainScene = new Scene(mainVBox(), 1200, 600);

        tableView.prefWidthProperty().bind(mainBox.widthProperty());
        tableView.prefHeightProperty().bind(mainBox.heightProperty());

        mainStage.setScene(mainScene);
        mainStage.show();
    }

    private GridPane mainGrid() {

        GridPane gridPane = new GridPane();
        gridPane.setVgap(10);
        gridPane.setHgap(10);

        gridPane.add(filename, 0, 0);
        gridPane.add(buttonBox(), 0, 1);
        gridPane.add(tableView, 0, 2);

        return gridPane;
    }

    private VBox buttonBox() {

        VBox buttonBox = new VBox();

        HBox firstRowBox = new HBox();
        HBox secRowBox = new HBox();

        firstRowBox.getChildren().addAll(fileChooserFile(), save, neu, settings);
        firstRowBox.setSpacing(5);
        secRowBox.getChildren().addAll(table, row, column, date);
        secRowBox.setSpacing(5);

        buttonBox.getChildren().addAll(firstRowBox, secRowBox);
        buttonBox.setSpacing(5);
        buttonBox.prefWidthProperty().bind(mainBox.widthProperty());

        return buttonBox;
    }

    private VBox mainVBox() {

        mainBox = new VBox();

        mainBox.prefWidthProperty().bind(mainStage.widthProperty().multiply(0.8));

        mainBox.setPadding(new Insets(10, 10, 10 ,10));
        mainBox.getChildren().add(mainGrid());

        return mainBox;
    }

    private void initButton() {

        fileChooser = new FileChooser();

        save = new Button("Save");
        save.setPrefWidth(100);
        neu = new Button("New");
        neu.setPrefWidth(100);
        settings = new Button("Settings");
        settings.setPrefWidth(100);
        table = new Button("Table");
        table.setPrefWidth(100);
        row = new Button("Row");
        row.setPrefWidth(100);
        column = new Button("Column");
        column.setPrefWidth(100);
        date = new Button("Date");
        date.setPrefWidth(100);
    }

    private Node fileChooserFile() {

        FileChooser.ExtensionFilter extFilter = new ExtensionFilter("Text File (*.txt)", "*.txt");
        fileChooser.getExtensionFilters().add(extFilter);

        final Button open = new Button("Open");
        open.setPrefWidth(100);
        open.setOnAction(ae -> openFileAction());

        return open;
    }

    private void openFileAction() {

        File input = fileChooser.showOpenDialog(mainStage);

        if (input != null) {

            try {

                String path = input.getParent();
                String fileName = input.getName();
                fileChooser.setInitialDirectory(new File(path));

                clearData();

            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void clearData() {

        tableView.getItems().clear();
        tableView.getColumns().clear();
        tableView.getStylesheets().clear();
        tableView.getProperties().clear();
        tableView.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
        tableView.getSortOrder().clear();
    }
}

Thank you for your help!

fabian :

The row and column index used for GridPane are stored in the properties map of a child node. If GridPane does not find the entries specifying the indices in the properties map, it treats this node as if you specified 0 for those indices moving it to the top left cell.

Note that resetting properties that are not even modified by your code is pointless. Currently that can be said about everything in your clearData method(, even clearing the items list), but let's go though the statements in that method line by line:

tableView.getItems().clear();

You'll probably keep this line. But with your current code you won't see a difference, since you do not add any items to the TableView.

tableView.getColumns().clear();

This may or may not be necessary. If you're just showing a single type of data and don't implement any modification of the displayed columns, you propably won't need this. It may also be useful, if you want to reset reordering of the columns done by the user.

tableView.getStylesheets().clear();

You do not add any stylesheets to the TableView. Unless you're planing to do so dynamically, this statement is unnecessary: It doesn't have any effect on the GUI. (Just make sure to not add the same stylesheet over and over again.)

tableView.getProperties().clear();

This is only necessary, if you store your own data in this map. There's no indication of this in your code though. If you want to use the map to store some data, I strongly recommend using the Map.remove(Object key) method to clear those keys you're using. If you insist on clearing the whole map, you need to make sure the layout properties stored in there are reassigned, e.g.

tableView.getProperties().clear();
GridPane.setRowIndex(tableView, 2);
GridPane.setColumnIndex(tableView, 0);

tableView.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);

There's no point in doing this, unless you assign some value other than the default value.

tableView.getSortOrder().clear();

May be necessary to reset any sorting done, but if you clear the columns anyways, you can remove this statement.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326535&siteId=1