从ColorPicker更新图表颜色

时间:2015-06-28 19:30:44

标签: javafx javafx-8

我正在使用此代码示例创建带颜色选择器的区域图表:

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.AnimationTimer;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MainApp extends Application
{

    private static final int MAX_DATA_POINTS = 50;

    private Series series;
    private int xSeriesData = 0;
    private final ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<>();
    private ExecutorService executor;
    private AddToQueue addToQueue;
    private Timeline timeline2;
    private NumberAxis xAxis;
    private NumberAxis yAxis;
    private AreaChart<Number, Number> sc;

    private void init(Stage primaryStage)
    {

        xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
        xAxis.setForceZeroInRange(false);
        xAxis.setAutoRanging(false);

        yAxis = new NumberAxis();
        yAxis.setAutoRanging(true);

        sc = new AreaChart<Number, Number>(xAxis, yAxis);
        sc.getStylesheets().add(getClass().getResource("/styles/AreaChart.css").toExternalForm());

        sc.setAnimated(false);
        sc.setId("liveAreaChart");
        sc.setTitle("Animated Area Chart");

        //-- Chart Series
        series = new AreaChart.Series<Number, Number>();
        series.setName("Area Chart Series");
        sc.getData().add(series);

        final ColorPicker colorPicker = new ColorPicker();

        colorPicker.setOnAction(new EventHandler()
        {
            @Override
            public void handle(Event t)
            {
                changeColor(colorPicker.getValue().getRed(), colorPicker.getValue().getGreen(), colorPicker.getValue().getBlue(), colorPicker.getValue().getOpacity());
            }
        });

        VBox root = new VBox(5, colorPicker, sc);

        primaryStage.setScene(new Scene(root));
    }

    private void changeColor(double redColor, double greenColor, double blueColor, double opacity)
    {
        int r = (int) Math.round(redColor * 255.0);
        int g = (int) Math.round(greenColor * 255.0);
        int b = (int) Math.round(blueColor * 255.0);

        sc.setStyle("CHART_COLOR_1: rgb(" + r + "," + g + "," + b + ");"
            + "CHART_COLOR_1_TRANS_20: rgba(" + r + "," + g + "," + b + "," + 0.2 + ");");
    }

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        init(primaryStage);
        primaryStage.show();

        //-- Prepare Executor Services
        //-- Prepare Executor Services
        executor = Executors.newCachedThreadPool(new ThreadFactory()
        {
            @Override
            public Thread newThread(Runnable r)
            {
                Thread thread = new Thread(r);
                thread.setDaemon(true);
                return thread;
            }
        });
        addToQueue = new AddToQueue();
        executor.execute(addToQueue);
        //-- Prepare Timeline
        prepareTimeline();
    }

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

    private class AddToQueue implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                // add a item of random data to queue
                dataQ.add(Math.random());
                Thread.sleep(50);
                executor.execute(this);
            }
            catch (InterruptedException ex)
            {
                Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    //-- Timeline gets called in the JavaFX Main thread
    private void prepareTimeline()
    {
        // Every frame to take any data from queue and add to chart
        new AnimationTimer()
        {
            @Override
            public void handle(long now)
            {
                addDataToSeries();
            }
        }.start();
    }

    private void addDataToSeries()
    {
        for (int i = 0; i < 20; i++)
        { //-- add 20 numbers to the plot+
            if (dataQ.isEmpty())
                break;
            series.getData().add(new AreaChart.Data(xSeriesData++, dataQ.remove()));
        }
        // remove points to keep us at no more than MAX_DATA_POINTS
        if (series.getData().size() > MAX_DATA_POINTS)
        {
            series.getData().remove(0, series.getData().size() - MAX_DATA_POINTS);
        }
        // update
        xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
        xAxis.setUpperBound(xSeriesData - 1);
    }
}

css代码

.default-color0.chart-series-area-fill{
    -fx-fill: linear-gradient(#f2f2f2, #d4d4d4);
    -fx-background-insets: 0 0 -1 0, 0, 1, 2;
    -fx-background-radius: 3px, 3px, 2px, 1px;
    -fx-opacity: 0.6;
}

.default-color0.chart-area-symbol {
    -fx-background-color: #d4d4d4;
    -fx-background-radius: 0;
}

.default-color0.chart-series-area-line{
    -fx-stroke: #989898; -fx-stroke-width: 1px;
}

.default-color0.chart-legend-item-symbol{
    -fx-background-radius: 0;
    -fx-background-color: #989898; -fx-stroke-width: 1px;
}

.chart-legend-item-symbol{
    -fx-background-radius: 0;
    -fx-pref-width: 16;
}

/*
 * Second default line chart style
 */
.default-color1.chart-series-area-fill{
    -fx-fill: linear-gradient(#EE2521, #FF615D);
    -fx-background-insets: 0 0 -1 0, 0, 1, 2;
    -fx-background-radius: 3px, 3px, 2px, 1px;
    -fx-opacity: 0.1;
}

.default-color1.chart-area-symbol {
    -fx-background-color: #FF615D;
    -fx-background-radius: 0;
}

.default-color1.chart-series-area-line{
    -fx-stroke: #EE2521; -fx-stroke-width: 1px;
}

.default-color1.chart-legend-item-symbol{
    -fx-background-radius: 0;
    -fx-background-color: #EE2521; -fx-stroke-width: 1px;
}

当我从ColorPicker更改颜色时,没有任何反应,因为我已经应用了外部CSS文件中的样式。

你知道造成这个问题的原因是什么吗?

1 个答案:

答案 0 :(得分:2)

您不能在css文件中使用CHART_COLOR_1CHART_COLOR_1_TRANS_20的任何引用。因此,如果您只是使用setStyle更改这些值,那么在视觉上不会发生任何事情,因为您对颜色值进行了硬编码,例如

.default-color0.chart-series-area-line{
    -fx-stroke: #989898; ...
}

这就是在modena.css中的内容:

.default-color0.chart-series-area-line { -fx-stroke: CHART_COLOR_1; }
相关问题