使用滑块更改文本颜色

时间:2016-10-28 13:41:40

标签: javafx colors slider

我正在尝试制作一个程序,允许用户通过单选按钮选择RGB颜色,并使用滑块将值更改为0 - 255。颜色更改应适用于文本。选择R,G或B时,文本中只应出现所选颜色(即如果选择绿色,则红色和蓝色值为0)。

目前该计划在某种程度上有效。例如,如果滑块位于值150,并且我选择了一种新颜色,然后移动滑块,则文本颜色设置为150,或者在任何情况下滑块设置为的值,然后再尝试将其移动到新的价值。如果我想要更新滑块,我必须在移动滑块之前选择一种新颜色。它仅为每种选定的颜色更新一次。我希望它能无缝更新所选颜色。代码示例如下:

public class Oblig5 extends Application {

    static int colorValue = 0;
    static int red = 0;
    static int green = 0;
    static int blue = 0;

    public static void main(String[] args) {

        launch(args);

    }

    public void start(Stage primaryStage) {
        // Create panes
        BorderPane bPane = new BorderPane();
        VBox vBox = new VBox();
        bPane.setLeft(vBox);

        // Create text and place it in the pane
        Text text = new Text("Oblig 5");
        text.setFont(Font.font("Times New Roman", FontWeight.NORMAL, FontPosture.REGULAR, 40));
        bPane.setCenter(text);

        // Create radio buttons and place them in the VBox
        RadioButton rbRed = new RadioButton("Red");
        RadioButton rbGreen = new RadioButton("Green");
        RadioButton rbBlue = new RadioButton("Blue");


        ToggleGroup group = new ToggleGroup();
        rbRed.setToggleGroup(group);
        rbGreen.setToggleGroup(group);
        rbBlue.setToggleGroup(group);

        // Create handlers for radiobuttons 
        rbRed.setOnAction(e -> {
            if (rbRed.isSelected()) {
                red = colorValue;
                green = 0;
                blue = 0;
            }
        });

        rbGreen.setOnAction(e -> {
            if (rbGreen.isSelected()) {
                red = 0;
                green = colorValue;
                blue = 0;
            }
        });

        rbBlue.setOnAction(e -> {
            if (rbBlue.isSelected()) {
                red = 0;
                green = 0;
                blue = colorValue;
            }
        });

        vBox.getChildren().addAll(rbRed, rbGreen, rbBlue);

        // Create a slider and place it in the BorderPane
        Slider slider = new Slider(0, 255, 135);
        slider.setShowTickLabels(true);
        slider.setShowTickMarks(true);
        bPane.setBottom(slider);
        bPane.setAlignment(slider, Pos.CENTER);

        // Create a handler for the slider
        slider.valueProperty().addListener(ov -> {
            colorValue = (int) slider.getValue();
            text.setFill(Color.rgb(red, green, blue));
        });

        // Create a scene and place it in the stage
        Scene scene = new Scene(bPane, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Oblig 5");
        primaryStage.show();

    }

}

非常感谢任何投入!

2 个答案:

答案 0 :(得分:5)

[注意:@fabian在我写这篇文章的时候发了一个答案。任何一个答案都可行,我想我也会发布这个,因为它显示了略有不同的技巧。像在JavaFX中一样,有多种好方法可以实现同样的目的。]

当所选按钮更改或滑块值更改时,您需要使用适当的值设置文本填充。现在,当所选按钮发生变化时,您只更新变量redgreenblue(但不更改文本填充),当滑块值发生变化时,使用setFill(...)redgreen致电blue,但不要更改这些变量的值。

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Slider;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Oblig5 extends Application {

    public static void main(String[] args) {

        launch(args);

    }

    public void start(Stage primaryStage) {
        // Create panes
        BorderPane bPane = new BorderPane();
        VBox vBox = new VBox();
        bPane.setLeft(vBox);

        Text text = new Text("Oblig 5");
        text.setFont(Font.font("Times New Roman", FontWeight.NORMAL, FontPosture.REGULAR, 40));
        bPane.setCenter(text);

        RadioButton rbRed = new RadioButton("Red");
        RadioButton rbGreen = new RadioButton("Green");
        RadioButton rbBlue = new RadioButton("Blue");


        ToggleGroup group = new ToggleGroup();
        rbRed.setToggleGroup(group);
        rbGreen.setToggleGroup(group);
        rbBlue.setToggleGroup(group);

        vBox.getChildren().addAll(rbRed, rbGreen, rbBlue);

        Slider slider = new Slider(0, 255, 135);
        slider.setShowTickLabels(true);
        slider.setShowTickMarks(true);
        bPane.setBottom(slider);
        BorderPane.setAlignment(slider, Pos.CENTER);

        // Create a handler for the updating text fill:
        ChangeListener<Object> updateListener = (obs, oldValue, newValue) -> {
            int colorValue = (int) slider.getValue() ;
            int red   =   rbRed.isSelected() ? colorValue : 0 ;
            int green = rbGreen.isSelected() ? colorValue : 0 ;
            int blue  =  rbBlue.isSelected() ? colorValue : 0 ;
            text.setFill(Color.rgb(red, green, blue));
        };
        slider.valueProperty().addListener(updateListener);
        group.selectedToggleProperty().addListener(updateListener);

        // Create a scene and place it in the stage
        Scene scene = new Scene(bPane, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Oblig 5");
        primaryStage.show();

    }


}

答案 1 :(得分:4)

您可以将Color设置为userData用于切换。这允许您根据滑块值和选定的切换为文本的fill属性创建绑定:

// create radio buttons and add color at full brightness
RadioButton rbRed = new RadioButton("Red");
rbRed.setUserData(Color.RED);
RadioButton rbGreen = new RadioButton("Green");
rbGreen.setUserData(Color.LIME);
RadioButton rbBlue = new RadioButton("Blue");
rbBlue.setUserData(Color.BLUE);

ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbGreen.setToggleGroup(group);
rbBlue.setToggleGroup(group);

group.selectToggle(rbRed);

...

// create binding based on toggle user data and slider value
text.fillProperty().bind(Bindings.createObjectBinding(() -> {
    Color color = (Color) group.getSelectedToggle().getUserData();

    // use color determined by toggle with brightness adjusted based on slider value
    return color.deriveColor(0, 1, slider.getValue() / slider.getMax(), 1);
}, slider.valueProperty(), group.selectedToggleProperty()));

请注意,使用这些代码段不需要保留侦听器。特别是应该删除更新文本填充的侦听器,因为尝试分配绑定属性会导致异常。