Hey all I am needing a hand with the following:
I am trying to add the “On Action” to my custom control I create in Scene Builder 2.0.
I will have a couple of these in my scene so I am wanting to be able to have only 1 handler for all those toggle buttons. Problem being is that my custom control does not have a “On Action” section in the Code: section like other controls do?
Most built in controls look like this for their Code: section:
How do I add this function to my custom control?
My switch button code:
package sliderswitchapp;
import javafx.animation.FillTransition;
import javafx.animation.ParallelTransition;
import javafx.animation.TranslateTransition;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontSmoothingType;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.util.Duration;
Text text;
Label label;
static Pane root = new Pane();
private BooleanProperty switchedOn = new SimpleBooleanProperty(false);
private SimpleStringProperty labelText = new SimpleStringProperty("");
private TranslateTransition translateAnimation = new TranslateTransition(Duration.seconds(0.25));
private TranslateTransition translateAnimation2 = new TranslateTransition(Duration.seconds(0.25));
private FillTransition fillAnimation = new FillTransition(Duration.seconds(0.25));
private ParallelTransition animation = new ParallelTransition(translateAnimation, fillAnimation);
private ParallelTransition animation2 = new ParallelTransition(translateAnimation2);
public void turnOn(Boolean _change) { switchedOn.set(_change); }
public void labelTXT(String theTXT) { label.setText(theTXT); }
public BooleanProperty switchedOnProperty() { return switchedOn; }
public SimpleStringProperty switchedOnPropertyLabel() { return labelText; }
public class SliderSwitch extends AnchorPane {
public SliderSwitch() {
Rectangle background = new Rectangle(20, 6);
background.setArcWidth(10);
background.setArcHeight(10);
background.setFill(Color.rgb(124, 124, 124));
background.setStroke(Color.SLATEGREY);
Circle trigger = new Circle(8);
trigger.setCenterX(5);
trigger.setCenterY(3);
trigger.setFill(Color.rgb(255, 221, 221));
trigger.setStroke(Color.rgb(104, 105, 107));
DropShadow shadow = new DropShadow();
shadow.setRadius(1);
trigger.setEffect(shadow);
text = new Text();
text.setVisible(false);
text.setFont(Font.font("Verdana", FontWeight.MEDIUM, 5));
text.setFill(Color.rgb(0, 0, 0));
text.setX(0);
text.setY(-6);
text.setTextAlignment(TextAlignment.CENTER);
text.setFontSmoothingType(FontSmoothingType.LCD);
text.textProperty().bind(Bindings.when(switchedOnProperty()).then("ON").otherwise("OFF"));
text.setOnMouseClicked(e -> { switchedOn.set(!switchedOn.get()); });
translateAnimation.setNode(trigger);
translateAnimation2.setNode(text);
label = new Label();
label.setVisible(false);
label.setFont(Font.font("Verdana", FontWeight.BOLD, 12));
label.setTextAlignment(TextAlignment.LEFT);
label.setLayoutX(26); //left/right
label.setLayoutY(-5); //up/down
label.textProperty().bindBidirectional(switchedOnPropertyLabel());
fillAnimation.setShape(trigger);
getChildren().addAll(background, trigger, label);
switchedOn.addListener((obs, oldState, newState) -> {
boolean isOn = newState.booleanValue();
translateAnimation.setToX(isOn ? 45 - 35 : 0);
translateAnimation2.setToX(isOn ? this.getTranslateX() + 11 : this.getTranslateX());
fillAnimation.setFromValue(isOn ? Color.rgb(255, 221, 221) : Color.rgb(218, 239, 219));
fillAnimation.setToValue(isOn ? Color.rgb(218, 239, 219) : Color.rgb(255, 221, 221));
animation.play();
animation2.play();
});
setOnMouseClicked(event -> {
switchedOn.set(!switchedOn.get());
});
}
}
And the FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import sliderswitchapp.*?>
<?import javafx.scene.shape.*?>
<?import application.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="248.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sliderswitchapp.Controller">
<children>
<Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="76.0" layoutX="24.0" layoutY="33.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
<SliderSwitch fx:id="toggle1" layoutX="98.0" layoutY="52.0" />
<SliderSwitch fx:id="toggle2" layoutX="85.0" layoutY="108.0" />
<CheckBox layoutX="51.0" layoutY="192.0" mnemonicParsing="false" text="CheckBox" />
</children>
</AnchorPane>
Currently I am doing this per button:
toggle1.switchedOnProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean switchOff, Boolean switchOn) {
System.out.println((switchOn) ? "Switched ON" : "Switched OFF");
}
})
So that gets pretty messy if I have a lot of buttons in the scene. Just having one event for all the buttons would be ideal.
Help would be great! Thanks!