aufty
aufty

Reputation: 417

Using one event handler for multiple actions

I was doing some homework today and I've accomplished all of the goals of the assignment, which I'm sure will get me full points.

In an earlier class, however, we used the same Event Handler for more than one action (in this example, you either type a color in the text field, or click a button to change the background color of the box).

I can't figure out how I would do that in this case... do I have to choose a Type in the constructor? If the first parameter could be a button or a textfield then I think that would help.

I'm just trying to figure out how to apply DRY (Don't Repeat Yourself), where ever I can.

public class ColorChooserApplication extends Application
{

@Override
public void start(Stage stage)
{
    // Create all UI components
    VBox backgroundBox = new VBox(10);
    backgroundBox.setPadding(new Insets(10));
    HBox topBox = new HBox(10);
    HBox bottomBox = new HBox(10);

    TextField colorPrompt = new TextField();
    colorPrompt.setOnAction(new ColorHandler(colorPrompt, backgroundBox));

    Button redButton = new Button("Red");
    redButton.setOnAction(new ButtonHandler(redButton, backgroundBox));

    Button whiteButton = new Button("White");
    whiteButton.setOnAction(new ButtonHandler(whiteButton, backgroundBox));

    Button blueButton = new Button("Blue");
    blueButton.setOnAction(new ButtonHandler(blueButton, backgroundBox));



    // Assemble
    topBox.getChildren().add(colorPrompt);
    bottomBox.getChildren().addAll(redButton, whiteButton, blueButton);

    backgroundBox.getChildren().addAll(topBox, bottomBox);
    backgroundBox.setAlignment(Pos.CENTER);
    topBox.setAlignment(Pos.CENTER);
    bottomBox.setAlignment(Pos.CENTER);

    // Set scene and show
    stage.setScene(new Scene(backgroundBox));
    stage.show();

}

class ColorHandler implements EventHandler<ActionEvent>
{

    TextField colorTf;
    VBox bgVbox;

    public ColorHandler(TextField colorTf, VBox bgVbox)
    {
        this.colorTf = colorTf;
        this.bgVbox = bgVbox;
    }

    @Override
    public void handle(ActionEvent event)
    {
        String color = colorTf.getText();
        bgVbox.setStyle("-fx-background-color:" + color);
    }

}

class ButtonHandler implements EventHandler<ActionEvent>
{

    Button colorButton;
    VBox bgVbox;

    public ButtonHandler(Button colorButton, VBox bgVbox)
    {
        this.colorButton = colorButton;
        this.bgVbox = bgVbox;
    }

    @Override
    public void handle(ActionEvent event)
    {
        String color = colorButton.getText();
        bgVbox.setStyle("-fx-background-color:" + color);
    }

}

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

}

Upvotes: 0

Views: 1084

Answers (1)

James_D
James_D

Reputation: 209714

If you're using Java 8, you can do

class ColorHandler implements EventHandler<ActionEvent> {
    Supplier<String> colorSupplier ;
    VBox bgVbox ;

    public ColorHandler(Supplier<String> colorSupplier, VBox bgVbox) {
        this.colorSupplier = colorSupplier ;
        this.bgVbox = bgVbox ;
    }

    @Override
    public void handle(ActionEvent event) {
        String color = colorSupplier.get();
        bgVbox.setStyle("-fx-background-color: "+color);
    }
}

and then

colorPrompt.setOnAction(new ColorHandler(colorPrompt::getText, backgroundBox));
redButton.setOnAction(new ColorHandler(redButton::getText, backgroundBox));

Note that all you need to provide for the first parameter is some function that returns the correct string for use in the css. So you can do things like

whiteButton.setOnAction(new ColorHandler(() -> "#ffffff", backgroundBox));
blueButton.setOnAction(new ColorHandler(() -> "cornflowerblue", backgroundBox));

etc.

Upvotes: 1

Related Questions