gpt4 book ai didi

java - 如何向 ComboBoxTableCell 添加键盘编辑支持

转载 作者:行者123 更新时间:2023-11-30 10:01:12 26 4
gpt4 key购买 nike

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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com