用服务替换线程

时间:2014-03-23 16:19:22

标签: javafx javafx-2 javafx-8

我使用JavaFX Thread来更新JavaFX图表。

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javafx.animation.AnimationTimer;
import javafx.scene.Node;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;

/**
 * A chart that fills in the area between a line of data points and the axes. Good for comparing accumulated totals over time.
 *
 * @see javafx.scene.chart.Chart
 * @see javafx.scene.chart.Axis
 * @see javafx.scene.chart.NumberAxis
 * @related charts/line/LineChart
 * @related charts/scatter/ScatterChart
 */
public class ChartTestOne
{

    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;

    public AreaChart<Number, Number> init()
    {
        xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
        xAxis.setForceZeroInRange(false);
        xAxis.setAutoRanging(false);

        xAxis.setTickLabelsVisible(false);
        xAxis.setTickMarkVisible(false);
        xAxis.setMinorTickVisible(false);

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

        //-- Chart
        final AreaChart<Number, Number> sc = new AreaChart<Number, Number>(xAxis, yAxis)
        {
            // Override to remove symbols on each data point
            @Override
            protected void dataItemAdded(Series<Number, Number> series, int itemIndex, Data<Number, Number> item)
            {
            }
        };
        sc.setAnimated(false);
        sc.setId("liveAreaChart");
        sc.setTitle("Animated Area Chart");

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

        // look up first series fill
        Node node = sc.lookup(".default-color0.chart-series-area-fill");
        // set the first series fill to translucent pale green
        node.setStyle("-fx-fill: linear-gradient(#f2f2f2, #d4d4d4);"
            + "  -fx-background-insets: 0 0 -1 0, 0, 1, 2;"
            + "  -fx-background-radius: 3px, 3px, 2px, 1px;");

        Node nodew = sc.lookup(".chart-series-area-line");
        // set the first series fill to translucent pale green
        nodew.setStyle("-fx-stroke: #989898; -fx-stroke-width: 1px; ");

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

        return sc;
    }

    private class AddToQueue implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                // add a item of random data to queue
                dataQ.add(Math.random());
                Thread.sleep(1150);
                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);
    }
}

我想使用JavaFX Service来生成图表值。你能帮我重构代码吗?

1 个答案:

答案 0 :(得分:1)

我的建议:

public class ChartTestOne
{

    private static final int MAX_DATA_POINTS = 50;

    private Series series;
    private int xSeriesData = 0;
    private final ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<>();
    private NumberAxis xAxis;

    public AreaChart<Number, Number> init()
    {
        xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
        xAxis.setForceZeroInRange(false);
        xAxis.setAutoRanging(false);

        xAxis.setTickLabelsVisible(false);
        xAxis.setTickMarkVisible(false);
        xAxis.setMinorTickVisible(false);

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

        // Chart
        final AreaChart<Number, Number> sc = new AreaChart<Number, Number>(xAxis, yAxis)
        {
            // Override to remove symbols on each data point
            @Override
            protected void dataItemAdded(Series<Number, Number> series, int itemIndex, Data<Number, Number> item)
            {
            }
        };
        sc.setAnimated(false);
        sc.setId("liveAreaChart");
        sc.setTitle("Animated Area Chart");

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

        // Look up first series fill
        Node node = sc.lookup(".default-color0.chart-series-area-fill");
        // Set the first series fill to translucent pale green
        node.setStyle("-fx-fill: linear-gradient(#f2f2f2, #d4d4d4);"
            + "  -fx-background-insets: 0 0 -1 0, 0, 1, 2;"
            + "  -fx-background-radius: 3px, 3px, 2px, 1px;");

        Node nodew = sc.lookup(".chart-series-area-line");
        // Set the first series fill to translucent pale green
        nodew.setStyle("-fx-stroke: #989898; -fx-stroke-width: 1px; ");

        boolean run = true;

        Task task = new Task<Void>()
        {
            @Override
            public Void call() throws InterruptedException
            {
                while (run)
                {
                    dataQ.add(Math.random());
                    Thread.sleep(1150);
                }
                return null;
            }
        };

        new Thread(task).start();

        // Prepare Timeline
        prepareTimeline();

        return sc;
    }

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