TextField的KeyEvent消耗不一致

时间:2018-01-02 02:29:14

标签: java javafx

我在TextField中有一个TableView和一个BorderPane

我想将程序范围的热键分配给密钥s的程序,因此我在EventListener <KeyEvent>上添加了BorderPane

这似乎完美无缺 - 桌子上按下的事件被传递到BorderPane,但创建文本的TextField中的事件在被送到我的听众之前被消耗了。

然后我想为Shift + s添加一个类似的热键。在这种情况下,TextField不使用KeyEvent,因此它将S(大写)字母键入TextField,但也将键事件传递给我的BorderPane而不是消耗该事件。

这是一个可运行的例子:

import java.util.Locale;
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class KeyEventIssue extends Application {

    @Override
    public void start ( Stage stage ) throws Exception {

        TextField textInput = new TextField();
        TableView <Locale> table = getFilledTable();

        BorderPane primaryContainer = new BorderPane();

        primaryContainer.setTop( textInput );
        primaryContainer.setCenter( table );

        primaryContainer.setOnKeyPressed( ( KeyEvent e ) -> { 
            if ( e.getCode() == KeyCode.S 
            && !e.isControlDown() && !e.isAltDown() && !e.isShiftDown() && !e.isMetaDown() ) {
                System.out.println ( "Heard s" );
                e.consume();
            } else if ( e.getCode() == KeyCode.S && e.isShiftDown() 
            && !e.isControlDown() && !e.isAltDown() && !e.isMetaDown() ) {
                System.out.println ( "Heard Shift + s" );
                e.consume();
            } 
        });

        Scene scene = new Scene( primaryContainer );
        stage.setScene( scene );
        stage.setWidth( 700 );
        stage.show();
    }

    private TableView <Locale> getFilledTable () {
        TableView <Locale> table = new TableView <>( FXCollections.observableArrayList( Locale.getAvailableLocales() ) );
        TableColumn <Locale, String> countryCode = new TableColumn <>( "CountryCode" );
        countryCode.setCellValueFactory( new PropertyValueFactory <>( "country" ) );
        TableColumn <Locale, String> language = new TableColumn <>( "Language" );
        language.setCellValueFactory( new PropertyValueFactory <>( "language" ) );

        TableColumn <Locale, Locale> local = new TableColumn <>( "Locale" );
        local.setCellValueFactory( c -> new SimpleObjectProperty <>( c.getValue() ) );

        language.setCellValueFactory( new PropertyValueFactory <>( "language" ) );

        table.setColumnResizePolicy( TableView.CONSTRAINED_RESIZE_POLICY );

        table.getColumns().addAll( countryCode, language, local );

        return table;
    }

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

您可以采取的措施来重现此问题:

  1. 编译并运行此程序
  2. 在Tableview有焦点时按s - 打印“Heard s” - good
  3. 当TextField具有焦点时按s - 没有打印任何内容,s放在文本框中 - 良好
  4. 在Tableview有焦点时按shift + s - 打印“Heard Shift + s” - good
  5. 在TextField具有焦点时按shift + s - 打印“Heard Shift + s”并在文本框中输入S - BAD - 不应打印任何内容
  6. 这在我看来是不一致的行为。我做错了什么,或者这是javafx中的错误?

    我可以通过检查文本框是否具有焦点来做一个解决方法,我可能会为我的项目执行此操作,但它有一些文本框,将来可能会添加更多文本框。我希望避免这样做,因为它会导致难以维护的代码。

1 个答案:

答案 0 :(得分:0)

我发布了一个错误报告。这是Java 8中的一个已知问题,根据Java开发人员的说法在Java 9中修复:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8194280