从浅绿色到深红色流动

时间:2018-05-30 05:09:49

标签: java javafx colors background-color

我希望您能够看到按钮被按下了多少次,我想用彩色制作这些广告。 简短说明浅绿色按钮按下一次,深红色按钮经常按下。

我用简单的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 :(得分:2)

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

答案 1 :(得分:1)

您可以根据这些颜色的rgb值实现简单的解决方案:

green  in rgb is (0,  255, 0)
yellow in rgb is (255,255, 0)
red in rgb is (255, 0 , 0)

所以你从绿色开始,增加红色直到你变黄,然后减少绿色直到你变红:

DateCell

请注意,更改次数有限,并由COLOR_INCREMENT的大小定义。 2次(255 / COLOR_INCREMENT)后,颜色保持红色。
可以进一步改进克服此限制。它还可以从动态(更改)COLOR_INCREMENT中受益。

编辑您当然可以使用相同的方法更改@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(); } } 以及单元工厂使用:

# example data
fac1 <- c("A","B", "C", "E", "F", "10", "11", "12", "19")
x1       <- c(NA,2,NA,3,4,5,6,7,NA)
data1    <- data.frame(fac1,x1, stringsAsFactors = F) 

library(dplyr)

# specify values to group together as a look up table
# (this is what you should create to specify your grouping philosophy)
look_up = data.frame(fac1 = c("C","E","10","12"),
                     group = c(1,1,2,2), stringsAsFactors = F)

look_up

#   fac1 group
# 1    C     1
# 2    E     1
# 3   10     2
# 4   12     2


# update look up table
# (you can create a look up table like this straight away if you prefer)
look_up = look_up %>% 
  group_by(group) %>% 
  mutate(fac2 = paste0(fac1, collapse = "-")) %>%
  ungroup() %>%
  select(-group)

look_up

# # A tibble: 4 x 2
#   fac1  fac2 
#   <chr> <chr>
# 1 C     C-E  
# 2 E     C-E  
# 3 10    10-12
# 4 12    10-12


data1 %>%
  left_join(look_up, by="fac1") %>%
  group_by(fac2 = ifelse(is.na(fac2), fac1, fac2)) %>%
  mutate(x1 = mean(x1, na.rm = T)) %>%
  ungroup()

# # A tibble: 9 x 3
#   fac1     x1 fac2 
#   <chr> <dbl> <chr>
# 1 A       NaN A    
# 2 B         2 B    
# 3 C         3 C-E  
# 4 E         3 C-E  
# 5 F         4 F    
# 6 10        6 10-12
# 7 11        6 11   
# 8 12        6 10-12
# 9 19      NaN 19