- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
ComboBoxTableCell
允许在编辑模式下将 ComboBox
添加到 TableCell
。如果 comboBox.show()
被调用(例如,弹出窗口正在显示),comboBox
会按预期对向下箭头和向上箭头键使用react,并结束编辑模式一旦进入被击中。我只想使用键盘控制编辑。我找不到使用键盘调用“comboBox.show()”的方法。
直到现在,我尝试使用 setOnKeyPressed
将回调添加到 ComboBoxTableCell
(在通过工厂方法创建期间)或 ComboBox
(通过使用 ComboBoxTableCell.getGraphic()
)。回调调用了 ComboBox.show()
来打开弹出窗口,但它们没有被调用(通过打印到回调中的 System.out
来验证)。
actColumn.setCellFactory(
new Callback<TableColumn<S,Object>, TableCell<S,Object>>() {
private ObservableList<Object> list=optionList;
@SuppressWarnings("unchecked")
@Override
public TableCell<S, Object> call(TableColumn<S, Object> param) {
final ComboBoxTableCell<S,Object> cell=
new ComboBoxTableCell<S,Object>(list);
cell.setConverter((StringConverter<Object>) converter);
cell.setOnKeyPressed(event -> {
cell.startEdit();
Node node=cell.getGraphic();
System.out.println(node);
if(node instanceof ComboBox) {
System.out.println("Hit Key.");
final ComboBox<?> box=(ComboBox<?>) node;
box.show();
}
});
//We have to forcefully fill the combobox member and set the
//graphic, because the cell does not init the ComboBox in
//its constructor
Platform.runLater(new Runnable() {
@Override public void run() {
cell.startEdit();
Node node=cell.getGraphic();
if(node instanceof ComboBox) {
ComboBox<?> box=(ComboBox<?>) node;
//Now we should have the combobox for this cell
box.setOnKeyPressed(event -> {
System.out.println("Hit Key.");
if(event.getCode()==KeyCode.DOWN) {
System.out.println("Hit Arrow.");
box.show();
}
});
}
//Stop editing again
cell.cancelEdit();
}
});
return cell;
}
});
除了这段代码很奇怪之外,当在单元格的编辑模式下按下一个键时,处理程序不会被调用(或者至少我没有得到任何输出)。
我希望能够选择一个 ComboBoxTableCell
,按下回车键(可能还有一个额外的键),然后内部 ComboBox
的弹出窗口应该在没有任何交互的情况下出现鼠标完成。
最佳答案
您可以子类化 ComboBoxTableCell
以添加您想要的行为。这是一个概念验证:
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.StringConverter;
public class AutoShowComboBoxTableCell<S, T> extends ComboBoxTableCell<S, T> {
/*
* May want to provide alternate constructors and static methods similar to
* the ComboBoxTableCell class (i.e. the superclass).
*/
private boolean enterPressed;
public AutoShowComboBoxTableCell(StringConverter<T> converter, ObservableList<T> values) {
super(converter, values);
getStyleClass().add("auto-show-combo-box-table-cell");
// Assumes TableView property is set only once (valid assumption?)
tableViewProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
// Need to know if editing was started by the user pressing
// the ENTER key (see #startEdit())
EventHandler<KeyEvent> filter = event -> {
if (event.getCode() == KeyCode.ENTER) {
enterPressed = event.getEventType() == KeyEvent.KEY_PRESSED;
}
};
// Possible memory leak? Consider using WeakEventHandler (read docs)
getTableView().addEventFilter(KeyEvent.KEY_PRESSED, filter);
getTableView().addEventFilter(KeyEvent.KEY_RELEASED, filter);
observable.removeListener(this);
}
});
}
@Override
public void startEdit() {
if (isEditing()) return;
super.startEdit();
if (isEditing()) {
if (enterPressed) {
// Cell was put into edit mode by the user pressing ENTER. This causes
// problems since *releasing* ENTER while the ComboBox has the focus
// results in the value being committed; this leads to the current value
// being committed *immediately* after entering edit mode—not what we want.
// To fix that we consume the first ENTER-released event and then let all
// subsequent events through (by removing the event filter).
addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<>() {
@Override public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.ENTER) {
event.consume();
removeEventFilter(KeyEvent.KEY_RELEASED, this);
}
}
});
}
ComboBox<?> comboBox = (ComboBox<?>) getGraphic();
comboBox.requestFocus(); // Needed to allow releasing ENTER to commit the value
comboBox.show();
}
}
@Override
public void cancelEdit() {
if (isEditing()) {
super.cancelEdit();
requestTableViewFocus();
}
}
@Override
public void commitEdit(T newValue) {
if (isEditing()) {
super.commitEdit(newValue);
requestTableViewFocus();
}
}
// Allows user to keep navigating the table via the keyboard
private void requestTableViewFocus() {
TableView<S> tableView = getTableView();
if (tableView != null) {
tableView.requestFocus();
}
}
}
注意:以上内容使用了实现细节的知识,包括在编辑开始时将图形设置为 ComboBox
的事实以及导致编辑要提交。实现细节如有更改,恕不另行通知。
关于java - 如何向 ComboBoxTableCell 添加键盘编辑支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57560923/
我有类似此类的 LocalDate ArrayList public class Item { private ArrayList dates; } 另一个类中的 TableColumn Ob
我有一个 cellFactory,它在 TableView 列中创建可编辑的 ComboBoxTableCell: Callback, TableCell> cellFacto
ComboBoxTableCell 允许在编辑模式下将 ComboBox 添加到 TableCell。如果 comboBox.show() 被调用(例如,弹出窗口正在显示),comboBox 会按预期
我使用的 JavaFX TableView 有 5 列(列的数据类型):任务 ID(int)、任务名称(字符串)、任务描述(字符串)、状态(字符串)和备注(字符串)。现在,我正在从具有相同列的数据库加
我想向 JavaFX8 中 TableView 中 ComboBoxTableCell 内的 ComboBox 添加一个处理程序。我可以看到 ComboBoxTableCell 类中有一个私有(pri
我有一个带有 ComboBoxTableCell 的 TableView,当使用默认实现时,用户必须单击三次 才能从 ComboBox 的列表中选择一个值。我希望当用户单击单元格时显示组合框列表。我的
我试图将组合框放入表格单元格中,但我不能。代码如下: private void cargaTablaDesglose() { TableColumn column1 = new TableCo
import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.
默认情况下,ComboBoxTableCell 在未被编辑时呈现为标签。我想更改该行为,以便它始终呈现为 ComboBox。但是我找不到方法。 基本上我有一个 TableView。一些列的类型是 Co
我有一个表格 View ,用户可以双击列行,组合框下拉列表将与项目列表一起出现。这里的问题是用户一次只能选择一个值,而我想允许用户选择多个值。 使用 ComboBoxTableCell 的现有实现 L
我是一名优秀的程序员,十分优秀!