我试图覆盖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;
}
}
有人知道是否有可能解决这个问题?
非常感谢你。
答案 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);
}
}