Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TableView键盘导航-为什么setOnKeyPressed在JavaFX11(OpenJFX)和JavaFX8中对TAB、SHIFT和x2B等键的行为不同;账单等?_Javafx_Event Handling_Tableview_Javafx 8_Openjfx - Fatal编程技术网

TableView键盘导航-为什么setOnKeyPressed在JavaFX11(OpenJFX)和JavaFX8中对TAB、SHIFT和x2B等键的行为不同;账单等?

TableView键盘导航-为什么setOnKeyPressed在JavaFX11(OpenJFX)和JavaFX8中对TAB、SHIFT和x2B等键的行为不同;账单等?,javafx,event-handling,tableview,javafx-8,openjfx,Javafx,Event Handling,Tableview,Javafx 8,Openjfx,我已将我的应用程序从JavaFX8升级到JavaFX11(OpenJDK和OpenJFX),并尝试通过键盘在表格视图中的表格单元格中导航来解决一个问题 在JavaFX8中,我使用setOnKeyPressed捕捉和处理键特殊键,例如TAB移动到下一个右单元格,SHIFT+TAB移动到上一个左单元格。效果很好 但是,当相同的代码在JavaFX11中运行时,TAB会将焦点从TableView移动到屏幕上的其他控件,SHIFT+TAB也会这样做,但控制顺序相反。这就好像JavaFX11正在恢复TAB和

我已将我的应用程序从JavaFX8升级到JavaFX11(OpenJDK和OpenJFX),并尝试通过键盘在
表格视图中的
表格单元格中导航来解决一个问题

在JavaFX8中,我使用
setOnKeyPressed
捕捉和处理键特殊键,例如TAB移动到下一个右单元格,SHIFT+TAB移动到上一个左单元格。效果很好

但是,当相同的代码在JavaFX11中运行时,TAB会将焦点从
TableView
移动到屏幕上的其他控件,SHIFT+TAB也会这样做,但控制顺序相反。这就好像JavaFX11正在恢复TAB和SHIFT+TAB的默认行为,并忽略
setOnKeyPressed

为什么会这样?JavaFX8和JavaFX11之间的wrt键盘导航是否发生了变化?我的代码是否有问题

我修改了JavaFX11代码以注册并使用
EventHandler
,而不是
setOnKeyPressed
。然后,键盘导航就像在JavaFX8中一样工作。但是,新的
EventHandler
正在与我的应用程序中的其他
EventHandler
发生冲突,我非常希望能够使用
setonkeypress

我一直在谷歌上搜索,但到目前为止只找到了一个参考文献,其中至少有一部分看起来像是同一个问题:。其他参考是针对JavaFX8或更早版本的

下面是一个MVCE演示了这个问题。相同的代码同时在JavaFX8和JavaFX11中运行。您可以在不进行事件处理的情况下运行它以查看默认行为,或者使用
setOnKeyPressed
EventHandler
查看使用TAB和SHIFT+TAB时的行为差异

我正在使用jdk1.8.0_202以及OpenJDK和OpenJFX的11.0.2版本,它们都在Windows7上的Netbeans 10.0中运行

package test009;

import java.util.Arrays;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.converter.DefaultStringConverter;

public class Test009 extends Application {

    private EventHandler<KeyEvent> keyEditingHandler;
    private ObservableList<DataModel> ol = FXCollections.observableArrayList();
    private TableView<DataModel> tv = new TableView();

    private Parent createContent() {

        loadDummyData();
        createTableColumns();
        tv.getSelectionModel().setCellSelectionEnabled(true);
        tv.setEditable(true);
        tv.setItems(ol);

        //******************************************************************************************
        //JavaFX8 code that doesn't appear to work in JavaFX11
/*
        tv.setOnKeyPressed(event -> {
            doTheKeyEvent(event);
        });
*/
        //******************************************************************************************
        //Code needed to achieve the same end in JavaFX11
/*
        registerKeyEventHandler();
        addKeyEditingHandler();
*/
        BorderPane content = new BorderPane();
        content.setCenter(tv);

        HBox hb = new HBox();
        hb.setPadding(new Insets(10D));
        hb.setSpacing(10D);
        hb.setAlignment(Pos.CENTER);
        Button btn1 = new Button("any old object");
        Button btn2 = new Button("another object");
        hb.getChildren().addAll(Arrays.asList(btn1, btn2));

        content.setTop(hb);

        return content;
    }

    public void registerKeyEventHandler() {

        keyEditingHandler = (KeyEvent event) -> {
            doTheKeyEvent(event);
        };

    }    

    private <S> void doTheKeyEvent(KeyEvent event) {

        final KeyCombination shiftTAB = new KeyCodeCombination(KeyCode.TAB, KeyCombination.SHIFT_DOWN);
        @SuppressWarnings("unchecked") TablePosition<DataModel, ?> pos = tv.getFocusModel().getFocusedCell();

        if ( shiftTAB.match(event) ) {

            tv.getSelectionModel().selectLeftCell();
            event.consume();

        } else if ( event.getCode() == KeyCode.TAB ) {

            tv.getSelectionModel().selectRightCell();
            event.consume();

        //... test for other keys and key combinations
        //... otherwise fall through to edit the TableCell

        } else if ( ! event.isControlDown() && ! event.isAltDown() ){

            tv.edit(pos.getRow(), tv.getVisibleLeafColumn(pos.getColumn()));

        }

    }

    public void addKeyEditingHandler() {

        tv.addEventFilter(KeyEvent.KEY_PRESSED, keyEditingHandler);

    }

    private void createTableColumns() {

        TableColumn<DataModel,String> col1 = new TableColumn<>("field1");
        TableColumn<DataModel,String> col2 = new TableColumn<>("field2");
        TableColumn<DataModel,String> col3 = new TableColumn<>("field3");
        TableColumn<DataModel,String> col4 = new TableColumn<>("field4");
        TableColumn<DataModel,String> col5 = new TableColumn<>("field5");

        col1.setCellValueFactory(cellData -> cellData.getValue().field1Property());
        col1.setCellFactory(TextFieldTableCell.<DataModel, String>forTableColumn(new DefaultStringConverter()));

        col2.setCellValueFactory(cellData -> cellData.getValue().field2Property());
        col2.setCellFactory(TextFieldTableCell.<DataModel, String>forTableColumn(new DefaultStringConverter()));

        col3.setCellValueFactory(cellData -> cellData.getValue().field3Property());
        col3.setCellFactory(TextFieldTableCell.<DataModel, String>forTableColumn(new DefaultStringConverter()));

        col4.setCellValueFactory(cellData -> cellData.getValue().field4Property());
        col4.setCellFactory(TextFieldTableCell.<DataModel, String>forTableColumn(new DefaultStringConverter()));

        col5.setCellValueFactory(cellData -> cellData.getValue().field5Property());
        col5.setCellFactory(TextFieldTableCell.<DataModel, String>forTableColumn(new DefaultStringConverter()));

        tv.getColumns().addAll(Arrays.asList(col1, col2, col3, col4, col5));

    }

    private void loadDummyData() {

        ol.add(new DataModel("1", "a", "x", "y", "z"));
        ol.add(new DataModel("2", "a", "x", "y", "z"));
        ol.add(new DataModel("3", "a", "x", "y", "z"));
        ol.add(new DataModel("4", "a", "x", "y", "z"));
        ol.add(new DataModel("5", "a", "x", "y", "z"));

    }

    private class DataModel {

        private final StringProperty field1;
        private final StringProperty field2;
        private final StringProperty field3;
        private final StringProperty field4;
        private final StringProperty field5;

        public DataModel(
            String field1,
            String field2,
            String field3,
            String field4,
            String field5
        ) {
            this.field1 = new SimpleStringProperty(field1);
            this.field2 = new SimpleStringProperty(field2);
            this.field3 = new SimpleStringProperty(field3);
            this.field4 = new SimpleStringProperty(field4);
            this.field5 = new SimpleStringProperty(field5);
        }

        public String getField1() {return field1.get().trim();}
        public void setField1(String field1) {this.field1.set(field1);}
        public StringProperty field1Property() {return field1;}

        public String getField2() {return field2.get().trim();}
        public void setField2(String field2) {this.field2.set(field2);}
        public StringProperty field2Property() {return field2;}

        public String getField3() {return field3.get().trim();}
        public void setField3(String field3) {this.field3.set(field3);}
        public StringProperty field3Property() {return field3;}

        public String getField4() {return field4.get().trim();}
        public void setField4(String field4) {this.field4.set(field4);}
        public StringProperty field4Property() {return field4;}

        public String getField5() {return field5.get().trim();}
        public void setField5(String field5) {this.field5.set(field5);}
        public StringProperty field5Property() {return field5;}

    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.setTitle("JavaFX11 - TableView keyboard navigation");
        stage.setWidth(600D);
        stage.setHeight(600D);
        stage.show();
    }

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

}
包test009;
导入java.util.array;
导入javafx.application.application;
导入静态javafx.application.application.launch;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.EventHandler;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.Parent;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TablePosition;
导入javafx.scene.control.TableView;
导入javafx.scene.control.cell.TextFieldTableCell;
导入javafx.scene.input.KeyCode;
导入javafx.scene.input.KeyCodeCombination;
导入javafx.scene.input.KeyCombination;
导入javafx.scene.input.KeyEvent;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.HBox;
导入javafx.stage.stage;
导入javafx.util.converter.DefaultStringConverter;
公共类Test009扩展了应用程序{
私有事件处理程序keyEditingHandler;
私有ObservableList ol=FXCollections.observableArrayList();
私有TableView tv=新建TableView();
私有父createContent(){
loadDummyData();
createTableColumns();
tv.getSelectionModel().setCellSelectionEnabled(true);
tv.setEditable(true);
设置项目(ol);
//******************************************************************************************
//在JavaFX11中似乎不起作用的JavaFX8代码
/*
tv.setOnKeyPressed(事件->{
doTheKeyEvent(事件);
});
*/
//******************************************************************************************
//在JavaFX11中实现相同目的所需的代码
/*
registerKeyEventHandler();
addKeyEditingHandler();
*/
边框窗格内容=新建边框窗格();
内容设置中心(电视);
HBox hb=新的HBox();
hb.设置填充(新插图(10D));
hb.起搏(10D);
hb.设置校准(位置中心);
按钮btn1=新按钮(“任何旧对象”);
按钮btn2=新按钮(“另一个对象”);
hb.getChildren().addAll(Arrays.asList(btn1,btn2));
setTop(hb);
返回内容;
}
公共无效注册表KeyEventHandler(){
keyEditingHandler=(KeyEvent事件)->{
doTheKeyEvent(事件);
};
}    
私有void doTheKeyEvent(KeyEvent事件){
final KeyCombination shiftTAB=新的keycodecompbination(KeyCode.TAB,KeyCombination.SHIFT_DOWN);
@SuppressWarnings(“未选中”)TablePosition pos=tv.getFocusModel().getFocusedCell();
如果(换档制动匹配(事件)){
tv.getSelectionModel().selectLeftCell();
event.consume();
}else if(event.getCode()==KeyCode.TAB){
tv.getSelectionModel().selectRightCell();
event.consume();
//…测试其他键和键组合
//…否则将无法编辑表格单元格
}如果(!event.isControlDown()&&!event.isAltDown()),则为else{
编辑(pos.getRow(),tv.getVisibleLeafColumn(pos.getColumn());
}
}
public void addKeyEditingHandler(){
tv.addEventFilter(按下KeyEvent.KEY_,编辑手柄);
}
私有void createTableColumns(){
TableColumn col1=新的TableColumn(“字段1”);
TableColumn col2=新的TableColumn(“字段2”);
TableColumn col3=新的TableColumn(“字段3”);
TableColumn col4=新的TableColumn(“字段4”);
TableColumn col5=新的TableColumn(“字段5”);
col1.setCellValueFactory(cellData->cellData.getValue().field1Property());
col1.setCellFactory(TextFieldTableCell.forTableColumn(新的DefaultStringConverter());
col2.setCellValueFactory(cellData->cellData.getValue().field2Property());
col2.setCellFactory(TextFieldTableCell.forTableColumn(新的DefaultStringConv