От светло-зеленого до темно-красного течет - PullRequest
0 голосов
/ 30 мая 2018

Я хочу, чтобы вы могли видеть, сколько раз была нажата кнопка, и я хотел бы сделать эту рекламу с цветами.Краткое объяснение: светло-зеленая кнопка была нажата один раз, а темно-красная кнопка была нажата очень часто.

Я решил это решение проблемы с помощью простого if.

If so (clicksCounter == 1) then green

Но это решение не очень элегантно, и мне понадобится много, если запросы будут от светло-зеленого до темно-красного.Теперь мой вопрос: кто-нибудь знает, как я могу свободно изменить цвет от светло-зеленого до темно-красного?

enter image description here

Под беглым пониманием подразумевается, чтоот светло-зеленого до темно-зеленого и «значений между», чтобы он выглядел более красивым.

И не, как в моем примере, только зеленый, желтый и красный, но изменение цвета должно быть плавным.

enter image description here enter image description here enter image description here


Main.java

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }


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

Controller.java

package sample;


import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;

import javax.security.auth.callback.Callback;
import java.net.URL;
import java.time.LocalDate;
import java.util.Date;
import java.util.ResourceBundle;

public class Controller implements Initializable {

    private int clicksCounter = 0;
    private String date = String.valueOf(LocalDate.now().getDayOfMonth());

    @FXML
    private Button button2;

    @FXML
    private DatePicker datePicker;

    @FXML
    private Label lbColor;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        button2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println(clicksCounter);
                clicksCounter++;
                if(clicksCounter == 1 ) {
                    lbColor.setStyle("-fx-background-color: #04b404;");
                }
                else if(clicksCounter == 2) {
                    lbColor.setStyle("-fx-background-color: #ffff13;");
                }
                else {
                    lbColor.setStyle("-fx-background-color: #df0101;");
                }

            }
        });

        javafx.util.Callback<DatePicker, DateCell> set = new javafx.util.Callback<DatePicker, DateCell>() {
            @Override
            public DateCell call(final DatePicker datePicker) {
                return new DateCell() {
                    @Override public void updateItem(LocalDate item, boolean empty) {
                        super.updateItem(item, empty);
                        //if today, change text and style
                        if (item.equals(LocalDate.now())) {
                            setText(date +"/" + clicksCounter);
                            if(clicksCounter == 1 ) {
                                setStyle("-fx-background-color: #04b404;");
                            }
                            else if(clicksCounter == 2) {
                                setStyle("-fx-background-color: #ffff13;");
                            }
                            else {
                                setStyle("-fx-background-color: #df0101;");
                            }
                        }
                    }
                };
            }
        };
        datePicker.setDayCellFactory(set);


    }
}

sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <Button fx:id="button2" layoutX="280.0" layoutY="48.0" mnemonicParsing="false" text="Click" />
      <DatePicker fx:id="datePicker" layoutX="45.0" layoutY="56.0" />
      <Label fx:id="lbColor" layoutX="191.0" layoutY="155.0" text="Color" />
   </children>
</AnchorPane>

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Вы можете реализовать простое решение, основанное на значениях rgb этих цветов:

green  in rgb is (0,  255, 0)<br/>
yellow in rgb is (255,255, 0)<br/>
red    in rgb is (255, 0 , 0)<br/>

Итак, вы начинаете с зеленого, увеличиваете красный до желтого, а затем уменьшаете зеленый до красного:

public class Controller implements Initializable {

    //defines the incremental change in color 
    private static final int COLOR_INCREMENT = 30;
    //initial rgb values (green) 
    private int red = 0, green = 255, blue = 0;
    @FXML
    private Button button2;

    @FXML
    private DatePicker datePicker;

    @FXML
    private Label lbColor;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        button2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                lbColor.setStyle("-fx-background-color:"+ getColorString()+";");
            }

        });
        //Cell factory omitted. Not needed to demonstrate the question nor the answer 
    }

    //increment color by COLOR_INCREMENT to step from green to yellow to red 
    //and return string representation of it 
    //green is rgb is (0, 255, 0)
    //yellow rgb is (255, 255, 0)
    //red in rgb is (255, 0, 0)
    private String getColorString() {

        if((green == 255) && (red < 255)) {
            red = (red + COLOR_INCREMENT) > 255 ?  255 : (red + COLOR_INCREMENT) ;
        }else if( (red == 255) && (green > 0)){
            green = (green - COLOR_INCREMENT) < 0 ?  0 : (green - COLOR_INCREMENT) ;
        }

        StringBuilder sb = new StringBuilder("rgb(");
        sb.append(red).append(",")
        .append(green).append(",")
        .append(blue).append(")");

        return sb.toString();
    }
}

Обратите внимание, что количество изменений ограничено и определяется размером COLOR_INCREMENT.Через 2 раза (255 / COLOR_INCREMENT) цвет остается красным.Это может быть дополнительно улучшено, преодолев этот предел.Также может быть полезно динамическое изменение (COLOR_INCREMENT)

Редактировать Вы, конечно, можете использовать тот же метод для изменения цвета DateCell:

@Override
public void initialize(URL location, ResourceBundle resources) {

    button2.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            lbColor.setStyle("-fx-background-color:"+ getColorString()+";");
        }

    });

    javafx.util.Callback<DatePicker, DateCell> set = new javafx.util.Callback<DatePicker, DateCell>() {
        @Override
        public DateCell call(final DatePicker datePicker) {
            return new DateCell() {
                @Override public void updateItem(LocalDate item, boolean empty) {
                    super.updateItem(item, empty);
                    //if today, change text and style
                    if (item.equals(LocalDate.now())) {
                        setText(date +"/" + clicksCounter);
                        setStyle("-fx-background-color: "+ getColorString () +"; ");
                    }
                }
            };
        }
    };
    datePicker.setDayCellFactory(set);
}

Обратите внимание, что вызов getColorString () дважды (один раз кнопкойобработчик и один раз по фабрике ячеек) вызывает изменение цвета дваждыЧтобы предотвратить это, вы можете установить цветное поле.Поле обновляется обработчиком кнопки и используется Label, а также фабрикой ячеек:

public class Controller implements Initializable {

    protected static final int COLOR_INCREMENT = 30;

    @FXML
    private Button button2;

    @FXML
    private DatePicker datePicker;

    @FXML
    private Label lbColor;

    private int red = 0, green = 255, blue = 0;
    private String colorAsString; //string representation of rgb color 
    private int clicksCounter = 0;
    private String date = String.valueOf(LocalDate.now().getDayOfMonth());

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        button2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                colorAsString = getColorString();
                lbColor.setStyle("-fx-background-color:"+ colorAsString +";");
            }
        });

        javafx.util.Callback<DatePicker, DateCell> set = new javafx.util.Callback<DatePicker, DateCell>() {
            @Override
            public DateCell call(final DatePicker datePicker) {
                return new DateCell() {
                    @Override public void updateItem(LocalDate item, boolean empty) {
                        super.updateItem(item, empty);
                        //if today, change text and style
                        if (item.equals(LocalDate.now())) {
                            setText(date +"/" + clicksCounter);
                            setStyle("-fx-background-color: "+ colorAsString +"; ");
                        }
                    }
                };
            }
        };
        datePicker.setDayCellFactory(set);
    }

    //increment color by COLOR_INCREMENT to step from green to yellow to red
    //and return string representation of it
    //green is rgb is (0, 255, 0)
    //yellow rgb is (255, 255, 0)
    //red in rgb is (255, 0, 0)
    private String getColorString() {

        if((green == 255) && (red < 255)) {
            red = (red + COLOR_INCREMENT) > 255 ?  255 : (red + COLOR_INCREMENT) ;
        }else if( (red == 255) && (green > 0)){
            green = (green - COLOR_INCREMENT) < 0 ?  0 : (green - COLOR_INCREMENT) ;
        }

        StringBuilder sb = new StringBuilder("rgb(");
        sb.append(red).append(",")
        .append(green).append(",")
        .append(blue).append(")");

        return sb.toString();
    }
}
0 голосов
/ 30 мая 2018

Color реализует интерфейс Interpolatable<Color>, поэтому API может выполнить интерполяцию за вас.

public class Controller implements Initializable {
    private static final Color GREEN = Color.web("#04b404");
    private static final Color YELLOW = Color.web("#ffff13");
    private static final Color RED = Color.web("#df0101");

    private static final double INCREMENT_STEP = 0.3d; // Adjust this

    private final DoubleProperty step = new SimpleDoubleProperty();
    private final ObjectBinding<Color> backgroundColor;

    public Controller {
        backgroundColor = Bindings.createObjectBinding(() -> {
            final double value = step.get() % 3.0; // We get modulus so that 0 <= value < 3

            switch((int) value) { // We will round down the value
                case 0:
                    return GREEN.interpolate(YELLOW, value % 1.0); // Get an interpolate value of 0.0-1.0
                case 1:
                    return YELLOW.interpolate(RED, value % 1.0);
                case 2:
                    return RED.interpolate(GREEN, value % 1.0);
                default:
                    return null; // Shouldn't happen at all
            }
        }, step);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        button2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                step.set(step.get() + INCREMENT_STEP);
            }
        });

        javafx.util.Callback<DatePicker, DateCell> set = new javafx.util.Callback<DatePicker, DateCell>() {
            @Override
            public DateCell call(final DatePicker datePicker) {
                return new DateCell() {
                    @Override public void updateItem(LocalDate item, boolean empty) {
                        super.updateItem(item, empty);
                        //if today, change text and style
                        if (item.equals(LocalDate.now())) {
                            setText(date +"/" + clicksCounter); // Not sure if you still need the click count
                            backgroundProperty().bind(Bindings.when(
                                    backgroundColor.isNotNull())
                                .then(Bindings.createObjectBinding(() -> 
                                    new Background(new BackgroundFill(
                                        backgroundColor.get(),
                                        CornerRadii.EMPTY,
                                        Insets.EMPTY
                                    )), backgroundColor)
                                ).otherwise(Background.EMPTY)
                            );
                        }
                    }
                };
            }
        };
        datePicker.setDayCellFactory(set);
    }
}
...