2016-10-28 2 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, 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(); 

    } 


} 
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

Смежные вопросы