我在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 );
}
}
您可以采取的措施来重现此问题:
s
- 打印“Heard s” - good s
- 没有打印任何内容,s
放在文本框中 - 良好 shift + s
- 打印“Heard Shift + s” - good shift + s
- 打印“Heard Shift + s”并在文本框中输入S
- BAD - 不应打印任何内容这在我看来是不一致的行为。我做错了什么,或者这是javafx中的错误?
我可以通过检查文本框是否具有焦点来做一个解决方法,我可能会为我的项目执行此操作,但它有一些文本框,将来可能会添加更多文本框。我希望避免这样做,因为它会导致难以维护的代码。
答案 0 :(得分:0)
我发布了一个错误报告。这是Java 8中的一个已知问题,根据Java开发人员的说法在Java 9中修复:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8194280