鼠标单击时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");
            }
        });