Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8194280

Inconsistent KeyEvent Consumption by TextField

XMLWordPrintable

    • generic
    • generic

      FULL PRODUCT VERSION :
      openjdk version "1.8.0_151"
      OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.17.10.2-b12)
      OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux My-PC 4.13.0-21-generic #24-Ubuntu SMP Mon Dec 18 17:29:16 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      I have a TextField and a TableView in a BorderPane.

      I wanted to assign program-wide hotkey to the program for the key s, so I put a EventListener <KeyEvent> on the BorderPane.

      This seemed to work perfectly -- events pressed on the table were passed through to the BorderPane but events in the TextField that created text were consumed before getting to my listener.

      I then wanted to add a similar hotkey for Shift + s. In this case, the TextField does not consume the KeyEvent, so it types the letter S (capital) into the TextField but also passes the key event to my BorderPane rather than consuming the event.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run this program
      Press s while Tableview has focus -- "Heard s" is printed -- good
      Press s while TextField has focus -- nothing is printed and the s is put in the text box -- good
      Press shift + s while Tableview has focus -- "Heard Shift + s" is printed -- good
      Press shift + s while TextField has focus -- "Heard Shift + s" is printed and S is put in the text box -- BAD -- nothing should print.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      In step 5, expect "Heard Shift + s" to not print
      ACTUAL -
      In step 5, expect "Heard Shift + s" is printed

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      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 );
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      You can manually check to see if the text area has focus before printing. This is unwieldy in a larger program, but can be done. Could lead to difficult to maintain code.

            pmangal Priyanka Mangal (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: