Herseept72
Herseept72

Reputation: 25

ChoiceBox Background Colour Wont Change With Certain Colours

For some reason the colour of the background won't change for certain colours. It doesn't change for "Yellow" or "Pink". The only reason I could think of is that those are AWT colours and it is using that instead of JavaFX colours but i am not sure why the others wouldn't do that.

Here is a picture of the issue and the intended result

This is my code for the colour changing of the ChoiceBox:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.collections.FXCollections;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Tooltip;
import javafx.stage.StageStyle;
import javafx.scene.paint.Color;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import java.text.DateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.util.Duration;
import java.io.InputStream;

    public class Clock extends Application {

        public Text text;

            @Override 
            public void start(Stage stage) {

                    DateFormat df = new SimpleDateFormat("EEE,MMM d yyyy - h:mm:ss a");
                    Date date = new Date();
                    String stringDate = df.format(date);

                    text = new Text(10, 60, stringDate);
                    Font font = null;

                    InputStream input = getClass().getResourceAsStream("/DIGITALDREAMFAT.ttf");

                    try {
                    font = Font.loadFont(input, 30); 
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    text.setFont(font);
                    text.setFill(Color.RED);


            Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0), new EventHandler<ActionEvent>() {

                    @Override
                    public void handle(ActionEvent actionEvent) {
                    Date update = new Date();
                    String stringNewDate = df.format(update);
                    text.setText(stringNewDate);
                    }
            }), new KeyFrame(Duration.seconds(1)));

            timeline.setCycleCount(Animation.INDEFINITE);
            timeline.play();

                    ChoiceBox colorChoice = new ChoiceBox(FXCollections.observableArrayList("Red", "Blue", "Green", "Yellow", "Pink", "Grey", "Black", "White"));

                    colorChoice.setOnAction(new EventHandler<ActionEvent>(){
                        public void handle(ActionEvent e) {
                            if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("Red")) {
                            colorChoice.setStyle("-fx-base: red");
                            text.setFill(Color.RED);
                            } else if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("Blue")) {
                            colorChoice.setStyle("-fx-base: blue");
                            text.setFill(Color.BLUE);
                            } else if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("Green")) {
                            colorChoice.setStyle("-fx-base: green");
                            text.setFill(Color.GREEN);
                            } else if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("Grey")) {
                            colorChoice.setStyle("-fx-base: grey");
                            text.setFill(Color.GREY);
                            } else if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("White")) {
                            colorChoice.setStyle("-fx-base: white");
                            text.setFill(Color.WHITE);
                            } else if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("Black")) {
                            colorChoice.setStyle("-fx-base: black");
                            text.setFill(Color.BLACK);
                            } else if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("Yellow")) {
                            colorChoice.setStyle("-fx-base: yellow");
                            text.setFill(Color.YELLOW);
                            } else if (colorChoice.getSelectionModel().getSelectedItem().toString().equals("Pink")) {
                            colorChoice.setStyle("-fx-base: pink");
                            text.setFill(Color.PINK);
                            } else {
                            colorChoice.setStyle("-fx-base: red");
                            text.setFill(Color.RED);
                            }
                        }
                    });

                    HBox hbox = new HBox(colorChoice);
                    Scene scene = new Scene(new Group(text, hbox));


                    hbox.setSpacing(10);

                    colorChoice.setTooltip(new Tooltip("Select Text Colour"));
                    colorChoice.getSelectionModel().selectFirst();


                    scene.setFill(Color.TRANSPARENT);

                    stage.setScene(scene);
                    stage.initStyle(StageStyle.TRANSPARENT);
                    stage.setX(0);
                    stage.setY(0);
                    stage.setWidth(710);
                    stage.setHeight(80);
                    stage.show(); 
            }

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

Upvotes: 1

Views: 838

Answers (2)

James_D
James_D

Reputation: 209358

The default color of the drop-down menu is the looked-up color -fx-control-inner-background: this in turn defaults to a very light version of -fx-base (it is 80% lighter than -fx-base). Thus if you start with a light color for -fx-base, such as yellow, it will be effectively completely lightened to near-white. If you replace -fx-control-inner-background for the choice box, you will get the desired effect.

Note you can get rid of the ridiculous if-else construct, since the selected item in the choice box contains all the information you need.

    ChoiceBox<String> colorChoice = new ChoiceBox<>(
            FXCollections.observableArrayList("Red", "Blue", "Green", "Yellow", "Pink", "Grey", "Black", "White"));

    colorChoice.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent e) {

            String choice = colorChoice.getSelectionModel().getSelectedItem() ;
            if (choice != null) {
                String color = choice.toLowerCase();
                colorChoice.setStyle("-fx-base: "+color+"; -fx-control-inner-background: -fx-base ;");
                text.setFill(Color.web(color));
            }
        }
    }); 

Upvotes: 1

Bo Halim
Bo Halim

Reputation: 1776

Here you're listening to the control itself and not the items, and the change will not take place, it always passes by the else condition, so when you click on the control it will choose the color by default red (no item is selected) so if you want to change the color of the ChoiceBox depeding on the selected item use this :

cb.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {

        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

            cb.setStyle("-fx-base:" + newValue.toLowerCase() + ";");


        }
    });

Note: This changes the control according to the selected item and not the item itself, and I would be surprised if there was a method that manages the cell property !

Good luck !

Upvotes: 0

Related Questions