我对事件处理的主题感到困惑。
我正在尝试实现一个游戏。我已经分别编写了游戏逻辑和GUI(在JavaFX上)。
下面是一些示例代码;我该怎么做才能使updateScoresLabel()
方法在执行setScore(...)
方法时运行?
public class MyGameLogic
{
private int scores=0;
public void setScore(int scores)
{
this.scores=scores;
}
public int getScore()
{
return scores;
}
}
public class JustAGUIExample
{
Label scoresLabel;
MyGameLogic gameLogic;
public void updateScoresLabel()
{
this.scoresLabel=gameLogic.getScore();
}
}
使用绑定而不是事件处理程序
当模型发生更改时,您不需要事件处理程序来完成标签更新。
您可以将标签属性绑定到模型属性,然后在更改模型时,标签将自动更新。
将问题中的代码调整为使用绑定。
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.control.Label;
public class MyGameLogic {
private IntegerProperty scores = new SimpleIntegerProperty(0);
public void setScore(int scores) {
this.scores.set(scores);
}
public int getScore() {
return scores.get();
}
public IntegerProperty scoreProperty() {
return scores;
}
}
class JustAGUIExample {
private Label scoresLabel;
private MyGameLogic gameLogic;
public JustAGUIExample() {
scoresLabel.textProperty().bind(
gameLogic.scoreProperty().asString()
);
}
}
在这个JavaFX井字游戏的例子中有很多这种绑定策略的例子。
对于更复杂的逻辑,请使用ChangeListener
假设你也想在比分变化时播放胜利的声音,你可以使用这样的东西:
class JustAGUIExample {
private Label scoresLabel;
private MyGameLogic gameLogic;
private AudioClip levelUpAudio = new AudioClip("levelup.mp3");
public JustAGUIExample() {
scoresLabel.textProperty().bind(
gameLogic.scoreProperty().asString()
);
gameLogic.scoreProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
levelUpAudio.play();
}
});
}
}
因此,ChangeListener有点像属性更改的事件侦听器。但我之所以这么说,是因为在JavaFX中,事件有自己独立的东西,通常是为GUI系统事件保留的,如鼠标点击、窗口大小调整通知、触摸板滑动等。
使用Java 8的语法更好:
gameLogic.scoreProperty().addListener((observable, oldValue, newValue) ->
levelUpAudio.play()
);
Java事件处理教程
尽管您的问题中的示例并不真正需要事件处理,但您可以阅读OracleJavaFX事件处理教程,了解事件的真实情况及其工作方式。
我对基于摆动的建议的思考
在编写JavaFX程序时,请忽略任何与Swing中的事件处理有关的建议。相反,要学会用JavaFX的方式来做这些事情,否则你只会混淆自己。
要让GUI运行事件,该类必须实现ActionListener。由此,必须将actionPerformed方法添加到该类中。
以下是的示例实现
//Run, help, and about are all buttons on this frame
public void actionPerformed(ActionEvent e){
if(e.getSource() == run){ //Check if the event was the run button being pressed
//Run the "run" program
}else if(e.getSource() == about){ //Check if the event was the about button being pressed
//Open welcome
}else if(e.getSource() == help){ //Check if the event was the help button being pressed
//Have the help screen appear
}
}