我正在尝试制作一个程序,允许用户通过单选按钮选择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();
}
}
非常感谢任何投入!
答案 0 :(得分:5)
[注意:@fabian在我写这篇文章的时候发了一个答案。任何一个答案都可行,我想我也会发布这个,因为它显示了略有不同的技巧。像在JavaFX中一样,有多种好方法可以实现同样的目的。]
当所选按钮更改或滑块值更改时,您需要使用适当的值设置文本填充。现在,当所选按钮发生变化时,您只更新变量red
,green
和blue
(但不更改文本填充),当滑块值发生变化时,使用setFill(...)
,red
和green
致电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()));
请注意,使用这些代码段不需要保留侦听器。特别是应该删除更新文本填充的侦听器,因为尝试分配绑定属性会导致异常。