将java滑块开关代码转换为场景生成器控件

问题描述 投票:0回答:1

嘿,我正在尝试找出如何将我的 JavaFX 滑块开关转换为 Scene Builder 2.0 控件,以便我可以在场景生成器中使用它。

我目前正在观看这 2 个 YouTube 视频:

要进行滑块开关: Youtube 视频#1

创建场景生成器控件: Youtube 视频#2

上面 2 个 YouTube 视频的问题在于,它展示了如何首先在 Scene Builder 2.0 中开始设计,这不是我在关注第一个 YouTube 视频时所做的方式。 那么有没有办法将我在java中的内容转移到场景生成器来创建控件?

我完整的滑块开关代码:

package application;
    
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
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.scene.Parent;
import javafx.scene.effect.DropShadow;
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;

public class Main extends Application {
    static Text text;
    static Pane root = new Pane();
    
    private Parent createContent() {
        root.setPrefSize(300, 300);
        TranslateTransition translateAnimation2 = new TranslateTransition(Duration.seconds(0.25));
        ParallelTransition animation2 = new ParallelTransition(translateAnimation2);
        Rectangle bg = new Rectangle(300, 300);
        ToggleSwitch toggle = new ToggleSwitch();

        toggle.setTranslateX(100);
        toggle.setTranslateY(100);
        text.setTranslateX(toggle.getTranslateX());
        text.setTranslateY(toggle.getTranslateY() + 9);
        translateAnimation2.setNode(text);
        root.getChildren().addAll(toggle, text);
        
        return root;
    }

    private static class ToggleSwitch extends Parent {
        private BooleanProperty switchedOn = new SimpleBooleanProperty(false);
        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 BooleanProperty switchedOnProperty() {
            return switchedOn;
        }

        public boolean checkSwitch() {
            switchedOn.set(!switchedOn.get());
            return switchedOn.get();
        }

        public ToggleSwitch() {
            Rectangle background = new Rectangle(30, 10);
            background.setArcWidth(10);
            background.setArcHeight(10);
            background.setFill(Color.rgb(255, 161, 161));
            background.setStroke(Color.SLATEGREY);

            Circle trigger = new Circle(10);
            trigger.setCenterX(8);
            trigger.setCenterY(6);
            trigger.setFill(Color.rgb(245, 245, 245));
            trigger.setStroke(Color.SLATEGREY);

            DropShadow shadow = new DropShadow();
            shadow.setRadius(2);
            trigger.setEffect(shadow);
            
            text = new Text();
            text.setFont(Font.font("Verdana", FontWeight.MEDIUM, 8));
            text.setFill(Color.rgb(0, 0, 0));
            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);
            
            fillAnimation.setShape(background);

            getChildren().addAll(background, trigger);
            
            switchedOn.addListener((obs, oldState, newState) -> {
                boolean isOn = newState.booleanValue();
                
                translateAnimation.setToX(isOn ? 45 - 30 : 0);
                translateAnimation2.setToX(isOn ? this.getTranslateX() + 17 : this.getTranslateX());
                fillAnimation.setFromValue(isOn ? Color.rgb(255, 161, 161) : Color.rgb(156, 240, 168));
                fillAnimation.setToValue(isOn ? Color.rgb(156, 240, 168) : Color.rgb(255, 161, 161));
                animation.play();
                animation2.play();
            });

            setOnMouseClicked(event -> {
                switchedOn.set(!switchedOn.get());
            });
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(new Scene(createContent()));
        primaryStage.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}
java eclipse javafx scenebuilder
1个回答
0
投票

遵循以下步骤:

在此示例中,我将所有内容压缩到单个模块和项目中。

步骤类似,这里不再重复。

场景生成器中的自定义控件:

toggle in scene builder

应用程序中的自定义控件:

toggle in app

ToggleSwitch.java

package org.example.customcomponent;

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.scene.Parent;
import javafx.scene.effect.DropShadow;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.*;
import javafx.util.Duration;

public class ToggleSwitch extends Parent {
    private BooleanProperty switchedOn = new SimpleBooleanProperty(false);
    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);

    private final Text text = new Text();

    public BooleanProperty switchedOnProperty() {
        return switchedOn;
    }

    public boolean checkSwitch() {
        switchedOn.set(!switchedOn.get());
        return switchedOn.get();
    }

    public Text getText() {
        return text;
    }

    public ToggleSwitch() {
        Rectangle background = new Rectangle(30, 10);
        background.setArcWidth(10);
        background.setArcHeight(10);
        background.setFill(Color.rgb(255, 161, 161));
        background.setStroke(Color.SLATEGREY);

        Circle trigger = new Circle(10);
        trigger.setCenterX(8);
        trigger.setCenterY(6);
        trigger.setFill(Color.rgb(245, 245, 245));
        trigger.setStroke(Color.SLATEGREY);

        DropShadow shadow = new DropShadow();
        shadow.setRadius(2);
        trigger.setEffect(shadow);

        text.setFont(Font.font("Verdana", FontWeight.MEDIUM, 8));
        text.setFill(Color.rgb(0, 0, 0));
        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);

        fillAnimation.setShape(background);

        getChildren().addAll(background, trigger);

        switchedOn.addListener((obs, oldState, newState) -> {
            boolean isOn = newState;

            translateAnimation.setToX(isOn ? 45 - 30 : 0);
            translateAnimation2.setToX(isOn ? this.getTranslateX() + 17 : this.getTranslateX());
            fillAnimation.setFromValue(isOn ? Color.rgb(255, 161, 161) : Color.rgb(156, 240, 168));
            fillAnimation.setToValue(isOn ? Color.rgb(156, 240, 168) : Color.rgb(255, 161, 161));
            animation.play();
            animation2.play();
        });

        setOnMouseClicked(event -> switchedOn.set(!switchedOn.get()));
    }
}

ToggleController.java

package org.example.customcomponent;

import javafx.fxml.FXML;
import javafx.scene.layout.VBox;

public class ToggleController {
    @FXML
    private VBox toggleContainer;

    @FXML
    private ToggleSwitch toggleSwitch;

    @FXML
    private void initialize() {
        toggleContainer.getChildren().add(
                toggleSwitch.getText()
        );

        toggleSwitch.switchedOnProperty().addListener((o, wasOn, isOn) ->
                System.out.println("Switch state: " + isOn)
        );
    }
}

ToggleApp.java

package org.example.customcomponent;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class ToggleApp extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader loader = new FXMLLoader(ToggleApp.class.getResource("toggle.fxml"));
        Parent toggle = loader.load();

        stage.setScene(new Scene(toggle));
        stage.show();
    }

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

切换.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.VBox?>
<?import org.example.customcomponent.ToggleSwitch?>

<VBox fx:id="toggleContainer" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="6.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.customcomponent.ToggleController">
   <children>
      <ToggleSwitch fx:id="toggleSwitch" />
   </children>
   <padding>
      <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
   </padding>
</VBox>

模块信息.java

module org.example.customcomponent {
    requires javafx.controls;
    requires javafx.fxml;

    opens org.example.customcomponent to javafx.fxml;
    exports org.example.customcomponent;
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>customcomponent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>customcomponent</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>21.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>21.0.3</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
© www.soinside.com 2019 - 2024. All rights reserved.