鼠标单击时JavaFX设置按钮样式
JavaFX setting Button style on Mouse Click
我正在处理的 Java 项目遇到问题:我在窗格上通过 javafx 中的代码创建按钮网格。这些按钮都是我编写的 javafx Button class 的子 class 类型。
这是 class 的 header:
private final String BASIC_STYLE = "-fx-font: 6 arial;";
private final String CLICKED_STYLE = "-fx-background-color: #0f0";
private int row;
private int col;
private String category;
private boolean selected = false;
在构造函数中,我执行以下操作:
this.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
toggleSelected();
}
});
这是 toggleSelected() 方法:
public void toggleSelected() {
this.selected = !selected;
this.setStyle(selected ? this.BASIC_STYLE : this.BASIC_STYLE+this.CLICKED_STYLE);
}
它基本上应该在您每次单击按钮时交换样式。当我单击该按钮时,该按钮首先被 OS 编辑(边框变为蓝色),只有在我第二次单击完全相同的按钮后,它才会变为绿色(我通过 setStyle 给它的样式)。
然而,selected 属性 在第一次点击时变为 true,在第二次点击时变为 false,这意味着我在按钮上单击一次,它得到一个蓝色边框并且 selected = true ,如果我第二次点击它,它会变成绿色并且 selected = false,如果我第三次点击它,它会再次正常,但 selected 会再次为真。
我发现第一次单击按钮会正确更改 "selected" 变量而不是样式,这真的很奇怪。为什么会发生这种情况,如何避免在单击按钮之前先 select 按钮?
你初始化
selected = false ;
和
setStyle(BASIC_STYLE);
但是您的事件处理程序强制执行该规则
selected == true -> setStyle(BASIC_STYLE);
selected == false -> setStyle(CLICKED_STYLE);
因此您的初始状态与您的处理程序强制执行的状态不一致。
从初始状态开始,您第一次单击时,selected
设置为 true
,这导致 setStyle(BASIC_STYLE)
(这是它已有的值,因此没有任何变化)。从此,一切按需切换。
您需要更改初始状态,或者切换处理程序中 setStyle(...)
调用的逻辑。
public class ButtonEnterAction extends Button {
boolean selected = true;
public ButtonEnterAction(String connect) {
setText(connect);
action();
}
public ButtonEnterAction() {
action();
}
private void action() {
EventHandler<KeyEvent> enterEvent = (KeyEvent event) -> {
if (event.getCode() == KeyCode.ENTER) {
fire();
}
};
addEventFilter(KeyEvent.KEY_PRESSED, enterEvent);
// setOnMouseEntered(new EventHandler<MouseEvent>() {
// @Override
// public void handle(MouseEvent me) {
// SepiaTone st = new SepiaTone();
// setEffect(st);
// }
// });
// setOnMouseExited(new EventHandler<MouseEvent>() {
// @Override
// public void handle(MouseEvent me) {
// setEffect(null);
// }
// });
}
@Override
public void fire() {
super.fire(); //To change body of generated methods, choose Tools | Templates.
if (selected) {
SepiaTone st = new SepiaTone();
setEffect(st);
} else {
setEffect(null);
}
selected = !selected;
}
}
在 ButtonEnterAction 中创建 Instant Class 就像。
ButtonEnterAction bea = new ButtonEnterAction("TestButton");
bea.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("hello");
}
});
我正在处理的 Java 项目遇到问题:我在窗格上通过 javafx 中的代码创建按钮网格。这些按钮都是我编写的 javafx Button class 的子 class 类型。
这是 class 的 header:
private final String BASIC_STYLE = "-fx-font: 6 arial;";
private final String CLICKED_STYLE = "-fx-background-color: #0f0";
private int row;
private int col;
private String category;
private boolean selected = false;
在构造函数中,我执行以下操作:
this.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
toggleSelected();
}
});
这是 toggleSelected() 方法:
public void toggleSelected() {
this.selected = !selected;
this.setStyle(selected ? this.BASIC_STYLE : this.BASIC_STYLE+this.CLICKED_STYLE);
}
它基本上应该在您每次单击按钮时交换样式。当我单击该按钮时,该按钮首先被 OS 编辑(边框变为蓝色),只有在我第二次单击完全相同的按钮后,它才会变为绿色(我通过 setStyle 给它的样式)。 然而,selected 属性 在第一次点击时变为 true,在第二次点击时变为 false,这意味着我在按钮上单击一次,它得到一个蓝色边框并且 selected = true ,如果我第二次点击它,它会变成绿色并且 selected = false,如果我第三次点击它,它会再次正常,但 selected 会再次为真。 我发现第一次单击按钮会正确更改 "selected" 变量而不是样式,这真的很奇怪。为什么会发生这种情况,如何避免在单击按钮之前先 select 按钮?
你初始化
selected = false ;
和
setStyle(BASIC_STYLE);
但是您的事件处理程序强制执行该规则
selected == true -> setStyle(BASIC_STYLE);
selected == false -> setStyle(CLICKED_STYLE);
因此您的初始状态与您的处理程序强制执行的状态不一致。
从初始状态开始,您第一次单击时,selected
设置为 true
,这导致 setStyle(BASIC_STYLE)
(这是它已有的值,因此没有任何变化)。从此,一切按需切换。
您需要更改初始状态,或者切换处理程序中 setStyle(...)
调用的逻辑。
public class ButtonEnterAction extends Button {
boolean selected = true;
public ButtonEnterAction(String connect) {
setText(connect);
action();
}
public ButtonEnterAction() {
action();
}
private void action() {
EventHandler<KeyEvent> enterEvent = (KeyEvent event) -> {
if (event.getCode() == KeyCode.ENTER) {
fire();
}
};
addEventFilter(KeyEvent.KEY_PRESSED, enterEvent);
// setOnMouseEntered(new EventHandler<MouseEvent>() {
// @Override
// public void handle(MouseEvent me) {
// SepiaTone st = new SepiaTone();
// setEffect(st);
// }
// });
// setOnMouseExited(new EventHandler<MouseEvent>() {
// @Override
// public void handle(MouseEvent me) {
// setEffect(null);
// }
// });
}
@Override
public void fire() {
super.fire(); //To change body of generated methods, choose Tools | Templates.
if (selected) {
SepiaTone st = new SepiaTone();
setEffect(st);
} else {
setEffect(null);
}
selected = !selected;
}
}
在 ButtonEnterAction 中创建 Instant Class 就像。
ButtonEnterAction bea = new ButtonEnterAction("TestButton");
bea.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("hello");
}
});