如何将事件处理程序与另一个方法调用并置?

时间:2019-07-19 21:55:02

标签: javafx actionevent

我在两个单独的类中有两个按钮,当第二个按钮被按下时,我想将第一个按钮的onAction更改为原始操作加上一个附加的方法调用。按下第一个按钮后,我希望它的onAction恢复为原始状态。

我目前的工作基本上是

  Button b1 = new Button("b1");
    b1.setOnAction((event)-> {
        oldActionMethod();
    });

   public void oldActionMethod(){
     //actual code
   }

b2.setOnAction((event)-> {
      //some stuff
      Button b1 = getB1(); 
      EventHandler<ActionEvent> temp = b1.getOnAction();
      b1.setOnAction((event) -> {
        b1class.oldActionMethod(); 
        additionalMethod();
        b1.setOnAction(temp);
      }); 
    });

为了完成这项工作,我不得不将原来在setOnAction lambda表达式中的代码块移至辅助函数。有没有更清洁的方法可以做到这一点?这样的东西会消除对辅助功能的需要?

b1.setOnAction((event)-> {
    //actual code
});

b2.setOnAction((event) -> {
        //stuff 
        Button b1 = getB1();
        EventHandler<ActionEvent> temp = b1.getOnAction();
        b1.setOnAction(b1.getOnAction() + methodCall());
        b1.setOnAction(temp);
        //stuff
});

我现在拥有它的方式确实可以使用,但是感觉确实很糟糕,所以我只是想知道是否有更好的选择,可以将actionEvent与另一个方法进行本质上的连接。同样,如果有一种方法不需要将原始事件存储在temp对象中并在最后将其重置。一个可能的解决方案是,如果我可以告诉b2下次按下b1时进行监听,但是当它们处于两个单独的类中时,我不知道是否有任何方法可以这样做。

1 个答案:

答案 0 :(得分:0)

一种解决方案是在两个包含Butto的类之间共享一个模型类。
请参阅以下mcve。为了方便起见,可以将整个代码复制粘贴到一个文件(FaMain.java)中并运行:

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class FxMain extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        Model model = new Model();
        AClass aClass = new AClass(model);
        BClass bClass = new BClass(model);
        Label show = new Label();
        show.textProperty().bind(model.getTextProperty());
        VBox root = new VBox(10);
        root.getChildren().addAll(aClass.getButton(),show, bClass.getButton());
        primaryStage.setScene(new Scene(root, 400,100));
        primaryStage.sizeToScene();
        primaryStage.show();
    }

    public static void main(final String[] args) {
        launch(args);
    }
}

class Model {

    private final BooleanProperty aButtonSelected;
    private final SimpleStringProperty textProperty;

    Model(){
        aButtonSelected = new SimpleBooleanProperty();
        textProperty= new SimpleStringProperty();
    }

    ObservableValue<? extends String> getTextProperty() {
        return textProperty;
    }

    BooleanProperty aButtonSelectedProperty(){
        return aButtonSelected;
    }

    void bButtonClicked() {
        textProperty.set(aButtonSelected.get() ? "Button clicked. Toggle IS selected" :
            "Button clicked. Toggle is NOT selected");
    }
}

class AClass{

    private final ToggleButton aButton;

    AClass(Model model) {
        aButton = new ToggleButton("Toogle");
        model.aButtonSelectedProperty().bind(aButton.selectedProperty());
    }

    ToggleButton getButton(){
        return aButton;
    }
}

class BClass{

    private final Button bButton;

    BClass(Model model) {
        bButton = new Button("Click");
        bButton.setOnAction(e->model.bButtonClicked());
    }

    Button getButton(){
        return bButton;
    }
}

enter image description here