JavaFX绑定小键盘时报无法从静态上下文引用非静态方法错误
错误原因
编译报错的核心原因是调用keyPress方法的方式错误:keyPress是MainWindowController的非静态成员方法,必须通过MainWindowController的实例对象调用,你在MainWindow的handle方法中直接写MainWindowController.keyPress(valueOfKey),是用类名直接调用实例方法,属于静态上下文调用非静态方法,就会触发这个报错,和你是否定义静态类没有关系。
另外你的代码还存在一个逻辑bug:对同一个Scene对象连续调用两次setOnKeyPressed,后设置的ESC关闭监听器会覆盖之前设置的按键处理监听器,就算解决了编译错误,小键盘输入逻辑也不会生效。
你贴的代码里还有两处语法笔误:两个类的package main行后多了多余的反引号,MainWindowController的import块末尾多了多余的分号,编译前记得删掉。
修复步骤
- 在
MainWindow类中新增成员变量,持有FXMLLoader加载得到的MainWindowController实例,不要每次使用都临时强转。 - 把两个分散的按键监听逻辑合并到同一个
setOnKeyPressed回调中,避免监听器被覆盖。 - 调用
keyPress方法时,通过持有的controller实例调用,不要直接用类名调用。
修正后的核心代码
MainWindow.java修改部分:
public class MainWindow extends Application { private static Stage historyStage; // 持有Controller实例引用 private MainWindowController mainController; @Override public void start(Stage stage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("MainWindowInterface.fxml")); Scene scene = new Scene(loader.load()); scene.setFill(Color.TRANSPARENT); stage.setScene(scene); stage.initStyle(StageStyle.TRANSPARENT); stage.setResizable(false); stage.setTitle("Calculator"); stage.getIcons().add(new Image(getClass().getResourceAsStream("../images/icon.png"))); // 初始化controller实例 mainController = loader.getController(); mainController.init(stage); stage.show(); // 合并所有按键逻辑到同一个监听器,避免覆盖 scene.setOnKeyPressed(event -> { if (event.getCode() == KeyCode.ESCAPE){ stage.close(); return; } String valueOfKey = event.getCode().toString(); mainController.keyPress(valueOfKey); }); createHistoryStage(); } // 其余原有方法(createHistoryStage、getHistoryStage、run等)保持不变 // 之前实现EventHandler接口的handle方法可以删除,逻辑已经合并到上述监听器中 }
MainWindowController.java不需要修改方法签名,只要删掉import块末尾多余的分号、package行多余的反引号即可。
内容的提问来源于stack exchange,提问作者Ruben Moons
相关产品推荐
相关产品推荐

