JavaFX tableView - 覆盖箭头键的行为

时间:2018-03-15 18:28:13

标签: javafx tableview scrollpane

我试图覆盖JavaFX上箭头键的行为 的tableView。我设法做到了,但现在我遇到了ScrollPane问题。

简而言之,我有一个包含3列(0,1,2)的TableView,并从2按下右箭头键我希望选择在下一行上移动1(不是0)。这样做了。

但是现在当我到达最后一行时,我无法找到重置Scrollpane的方法。有了Swing,我就可以开展类似的项目了。

这是我的SSCCE - 不是那么简短,我知道

package application;

import java.util.ArrayList;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

class TVScrollPane extends ScrollPane {

    public int row;
    public int col;

    public TableView<TableViewRecord> tableView;
        public TableColumn<TableViewRecord, String> tableColumnA;
        public TableColumn<TableViewRecord, String> tableColumnB;
        public TableColumn<TableViewRecord, String> tableColumnC;

    public TVScrollPane() throws Exception {

        /* set columns */
        tableColumnA = new TableColumn<TableViewRecord, String>("column A");
        tableColumnA.setCellValueFactory(new PropertyValueFactory<TableViewRecord, String>("columnA"));
        tableColumnB = new TableColumn<TableViewRecord, String>("column B");
        tableColumnB.setCellValueFactory(new PropertyValueFactory<TableViewRecord, String>("columnB"));
        tableColumnC = new TableColumn<TableViewRecord, String>("column C");
        tableColumnC.setCellValueFactory(new PropertyValueFactory<TableViewRecord, String>("columnC"));

        /* set tableView */
        tableView = new TableView<TableViewRecord>();
        tableView.getColumns().add(tableColumnA);
        tableView.getColumns().add(tableColumnB);
        tableView.getColumns().add(tableColumnC);
        tableView.getSelectionModel().setCellSelectionEnabled(true);

        /* add records */
        ArrayList<TableViewRecord> al = new ArrayList<TableViewRecord>();
        for(int i = 0; i <= 20; ++i) {
            al.add(new TableViewRecord());
        }
        tableView.setItems(FXCollections.observableArrayList(al));

        /* row/column registration */
        if (tableView.getSelectionModel().getSelectedCells().size() != 0) {
            row = tableView.getSelectionModel().getSelectedCells().get(0).getRow();
            col = tableView.getSelectionModel().getSelectedCells().get(0).getColumn();
        }

        /* set on actions */
        tableView.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent e) {
                if (e.isPrimaryButtonDown()) {
                    if (tableView.getSelectionModel().getSelectedCells().size() != 0) {
                        row = tableView.getSelectionModel().getSelectedCells().get(0).getRow();
                        col = tableView.getSelectionModel().getSelectedCells().get(0).getColumn();
                    }
                }
            }
        });
        tableView.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent e) {
                if (e.getCode() == KeyCode.RIGHT) {
                    switch (e.getCode()) {
                    case RIGHT:
                        if (row < tableView.getItems().size()) {
                            switch (col) {
                            case 0:        col = 1; break;
                            case 1:        col = 2; break;
                            case 2: ++row; col = 1; break;
                            }
                        }
                        break;
                    default:
                        break;
                    }
                    int r = row;
                    TableColumn<TableViewRecord, ?> tc = tableView.getColumns().get(col);
                    tableView.getSelectionModel().select(r, tc);
                    tableView.getSelectionModel().getSelectedIndex();
                }
            }
        });

        /* set content */
        setContent(tableView);

    }

}

public class Main extends Application {

    @Override
    public void init() {}

    @Override
    public void start(Stage s) {
        try {
            s.setScene(new Scene(new TVScrollPane()));
            s.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

}

这是tableView记录描述的类:它必须是公共的并且在单独的类文件中:

package application;

public class TableViewRecord {

    private static Integer tvRecordsCounter = 0;

    private String columnA;
    private String columnB;
    private String columnC;

    public String getColumnA() { return columnA; }
    public String getColumnB() { return columnB; }
    public String getColumnC() { return columnC; }

    public TableViewRecord() {
        ++tvRecordsCounter;
        columnA = "a_" + tvRecordsCounter;
        columnB = "b_" + tvRecordsCounter;
        columnC = "c_" + tvRecordsCounter;
    }

}

有人知道是否有可能解决这个问题?

非常感谢你。

1 个答案:

答案 0 :(得分:1)

从kleopatra的建议开始,我找到了一种直接从TableView与Skin滚动管理器交互的方法,并找到了这个很好的scrollTo()方法:

https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TableView.html#scrollTo-int-

这是一个固定高度和可见列数

的解决方案
package application3;

import java.util.ArrayList;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

class testTableView extends TableView<TableViewRecord> {

    public static final int TABLE_VIEW_HEIGHT = 350;
    public static final int VISIBLE_ROWS_NUMBER = 13;

    public int row;
    public int col;

    public TableColumn<TableViewRecord, String> tableColumnA;
    public TableColumn<TableViewRecord, String> tableColumnB;
    public TableColumn<TableViewRecord, String> tableColumnC;

    public testTableView() throws Exception {

        /* set columns */
        tableColumnA = new TableColumn<TableViewRecord, String>("column A");
        tableColumnA.setCellValueFactory(new PropertyValueFactory<TableViewRecord, String>("columnA"));
        tableColumnB = new TableColumn<TableViewRecord, String>("column B");
        tableColumnB.setCellValueFactory(new PropertyValueFactory<TableViewRecord, String>("columnB"));
        tableColumnC = new TableColumn<TableViewRecord, String>("column C");
        tableColumnC.setCellValueFactory(new PropertyValueFactory<TableViewRecord, String>("columnC"));

        /* set tableView */
        getColumns().add(tableColumnA);
        getColumns().add(tableColumnB);
        getColumns().add(tableColumnC);
        getSelectionModel().setCellSelectionEnabled(true);

        /* add records */
        ArrayList<TableViewRecord> al = new ArrayList<TableViewRecord>();
        for(int i = 0; i <= 500; ++i) {
            al.add(new TableViewRecord());
        }
        setItems(FXCollections.observableArrayList(al));

        setPrefHeight(TABLE_VIEW_HEIGHT);

        /* row/column registration */
        if (getSelectionModel().getSelectedCells().size() != 0) {
            row = getSelectionModel().getSelectedCells().get(0).getRow();
            col = getSelectionModel().getSelectedCells().get(0).getColumn();
        }

        /* set on actions */
        setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent e) {
                if (e.isPrimaryButtonDown()) {
                    if (getSelectionModel().getSelectedCells().size() != 0) {
                        row = getSelectionModel().getSelectedCells().get(0).getRow();
                        col = getSelectionModel().getSelectedCells().get(0).getColumn();
                    }
                }
            }
        });
        setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent e) {
                if (e.getCode() == KeyCode.RIGHT) {
                    switch (e.getCode()) {
                    case RIGHT:
                        if (row < getItems().size()) {
                            switch (col) {
                            case 0:        col = 1; break;
                            case 1:        col = 2; break;
                            case 2: ++row; col = 1; break;
                            }
                        }
                        break;
                    default:
                        break;
                    }
                    int r = row;
                    TableColumn<TableViewRecord, ?> tc = getColumns().get(col);
                    getSelectionModel().select(r, tc);
                    if (r <= VISIBLE_ROWS_NUMBER - 1) {
                        scrollTo(0);
                    } else {
                        scrollTo(r - VISIBLE_ROWS_NUMBER + 1);
                    }
                }
            }
        });

    }

}

public class Main extends Application {

    @Override
    public void init() {}

    @Override
    public void start(Stage s) {
        try {
            s.setScene(new Scene(new testTableView()));
            s.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

}