2016-10-28 123 views
1

我想制作一个程序,允许用户通过单选按钮选择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(); 

    } 

} 

任何输入值得高度赞赏!

回答

5

[注:@fabian在写这篇文章时发布了一个答案。要么答案是可行的,我想我也会发布这个,因为它显示了稍微不同的技术。像往常一样在JavaFX中有多种好方法来实现同样的事情。]

当选定的按钮更改或滑块值更改时,您需要设置文本填充相应的值。此时,当所选按钮更改时,只更新变量red,​​和blue(但不要更改文本填充),并且当滑块值更改时,您可以拨打setFill(...)red,​​和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(); 

    } 


} 
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())); 

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

+0

感谢您的回复!由于这是一个学校任务,教授听众的使用,另一个答案更多地被选为解决方案。无论如何,我已经收到了满意的答复,因为您的答案似乎也是一个很好的选择。 – Esben86