一个控制多个点击监听器

Min*_*Brc 0 java user-interface javafx

我正在使用答案CustomButton中的自定义切换按钮。正如您在构造函数中看到的,单击侦听器将设置为按钮和对象本身。在主控制器类中,我创建了它的一个实例并设置了一个鼠标单击事件侦听器,以便根据其状态更新 UI,但这导致了一种奇怪的行为,在某些单击时,按钮会切换并更改颜色,有时用户界面将更新...

这就是我在MainController中创建和添加点击侦听器的方式:

filterSwitchButton = new SwitchButton();
    filterSwitchButton.setId("filterSwitchButton");
    HBox.setMargin(filterSwitchButton, new Insets(0, 20, 0, 50));
    filterSwitchButton.setOnMouseClicked(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            // update UI
        }
    });
Run Code Online (Sandbox Code Playgroud)

如何更新 UI 并更改单击切换按钮时的状态?

Sep*_*phB 5

您链接到的问题中的按钮可能不是合适的起点。

它调用setOnMouseClicked来添加它的自定义功能,但它的用户(在本例中为您)也应该调用它来添加您自己的功能。

要使其按原样工作,您可以获取当前引用,然后在您自己的处理程序开始时调用它。喜欢:

filterSwitchButton = new SwitchButton();
filterSwitchButton.setId("filterSwitchButton");
HBox.setMargin(filterSwitchButton, new Insets(0, 20, 0, 50));
EventHandler<MouseEvent> existingEvent = filterSwitchButton.getOnMouseClicked();
filterSwitchButton.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {
        existingEvent.handle(event);
        // update UI
    }
});
Run Code Online (Sandbox Code Playgroud)

编辑:这个按钮应该更适合你。它使用更 javafxy 的方式来处理它,并且设置鼠标单击处理程序应该更接近您的期望。可能仍然不完美,但它应该可以立即发挥作用,并且您可以通过稍后改进来学习。它还允许您通过代码和处理程序控制状态。

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;

public class SwitchButton extends StackPane {
    private final Rectangle back = new Rectangle(30, 10, Color.RED);
    private final Button button = new Button();
    private final String buttonStyleOff = "-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.2), 0.2, 0.0, 0.0, 2); -fx-background-color: WHITE;";
    private final String buttonStyleOn = "-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.2), 0.2, 0.0, 0.0, 2); -fx-background-color: #00893d;";
    private final BooleanProperty state = new SimpleBooleanProperty(false);

    private void init() {
        getChildren().addAll(back, button);
        setMinSize(30, 15);
        back.maxWidth(30);
        back.minWidth(30);
        back.maxHeight(10);
        back.minHeight(10);
        back.setArcHeight(back.getHeight());
        back.setArcWidth(back.getHeight());
        back.setFill(Color.valueOf("#ced5da"));
        Double r = 2.0;
        button.setShape(new Circle(r));
        setAlignment(button, Pos.CENTER_LEFT);
        button.setMaxSize(15, 15);
        button.setMinSize(15, 15);
        button.setStyle(buttonStyleOff);
        state.addListener(observable -> {
            if (state.get()) {
                button.setStyle(buttonStyleOff);
                back.setFill(Color.valueOf("#ced5da"));
                setAlignment(button, Pos.CENTER_LEFT);
            } else {
                button.setStyle(buttonStyleOn);
                back.setFill(Color.valueOf("#80C49E"));
                setAlignment(button, Pos.CENTER_RIGHT);
            }
        });
        button.setFocusTraversable(false);
        button.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEvent ->  state.set(!state.get()));
        button.onMouseClickedProperty().bind(onMouseClickedProperty());
    }

    public boolean isState() {
        return state.get();
    }

    public BooleanProperty stateProperty() {
        return state;
    }

    public void setState(boolean state) {
        this.state.set(state);
    }

    public SwitchButton() {
        init();
    }
}
Run Code Online (Sandbox Code Playgroud)


jew*_*sea 5

这是对之前相关问题的回答:

公开on对开关状态进行建模的属性。

该解决方案类似于SephB 的更新答案

如果开发人员想要在on属性状态更改时执行某些操作,他们可以侦听该on属性,而不是在控件中公开的内部节点上使用事件处理程序。可以根据需要将任意数量的此类属性更改侦听器添加到属性中。

同样,该on属性可用于更改开关状态,这将反映在 UI 中,并且生成的更改事件也将传播到任何定义的侦听器。

例如:

Switch lightSwitch = new Switch();
lightSwitch.onProperty().addListener((observable, wasOn, nowOn) -> {
    System.out.println(nowOn ? "on" : "off");
});

lightSwitch.setOn(true);
Run Code Online (Sandbox Code Playgroud)

将打印“ on”。