每 500 毫秒平滑渲染 Swing 组件 [英] Rendering Swing component smoothly every 500 millisecond

查看:18
本文介绍了每 500 毫秒平滑渲染 Swing 组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我每 500 毫秒调用 paintComponent() 以显示更新的图表时,我遇到了渲染问题.我在 Panel 上使用 JFreeChart 创建了大约 30 个条形图.

import java.awt.BorderLayout;导入 java.awt.Dimension;导入 java.awt.EventQueue;导入 java.awt.GridLayout;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;导入 java.util.Random;导入 javax.swing.JFrame;导入 javax.swing.JPanel;导入 javax.swing.Timer;导入 org.jfree.chart.ChartFactory;导入 org.jfree.chart.ChartPanel;导入 org.jfree.chart.JFreeChart;导入 org.jfree.chart.plot.PlotOrientation;导入 org.jfree.data.xy.XYSeries;导入 org.jfree.data.xy.XYSeriesCollection;/*** @see http://stackoverflow.com/a/38512314/230513* @see http://stackoverflow.com/a/15715096/230513* @see http://stackoverflow.com/a/11949899/230513*/公共类测试{私有静态最终 int N = 128;私有静态最终随机随机=新随机();私有整数 n = 1;私人无效显示(){JFrame f = new JFrame("TabChart");f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel p = new JPanel(new GridLayout(0, 1));for (int i = 0; i <3; i++) {p.add(createPane());}f.add(p, BorderLayout.CENTER);f.pack();f.setLocationRelativeTo(null);f.setVisible(true);}私人 ChartPanel createPane() {最终 XYSeries 系列 = new XYSeries("Data");for (int i = 0; i < random.nextInt(N) + N/2; i++) {series.add(i, random.nextGaussian());}XYSeriesCollection 数据集 = 新的 XYSeriesCollection(series);新定时器(500,新动作监听器(){@覆盖public void actionPerformed(ActionEvent e) {series.add(series.getItemCount(), random.nextGaussian());}}).开始();JFreeChart 图表 = ChartFactory.createXYLineChart("Test", "Domain","范围", 数据集, PlotOrientation.VERTICAL, false, false, false);返回新图表面板(图表){@覆盖公共维度 getPreferredSize() {返回新维度(480, 240);}};}公共静态无效主(字符串 [] args){EventQueue.invokeLater(new Runnable() {@覆盖公共无效运行(){新测试().显示();}});}}

I am facing rendering problem when I call paintComponent() every 500 millisecond to show updated charts. I have around 30 barcharts created by using JFreeChart on Panel.

Rendering with error and How can I solve this problem?

private void ShowGraphs() {

   FirstChart.removeAll();
   SecondChart.removeAll();
   ThirdChart.removeAll();
   FirstChart.add(Label1);
   SecondChart.add(Label2);
   ThirdChart.add(Label3);

   ChartUpdate(P1,FirstChart);
   ChartUpdate(P2,SecondChart);
   ChartUpdate(P3,ThirdChart);
   //FirstChart, SecondChart, ThirdChart is JPanels
   //Tabb is JTabbedPane
   paintComponents(Tabb.getGraphics());
}

This code is called every 500 milliseconds and ChartUpdate(MyObject, Panel) is chart building function on Panel using MyObject's info.

解决方案

Don't replace the view component. Instead, update the corresponding model and the listening view will update itself in response. In the example below, each ChartPanel returned by createPane() has a Swing Timer that updates its XYSeries every 500 ms.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * @see http://stackoverflow.com/a/38512314/230513
 * @see http://stackoverflow.com/a/15715096/230513
 * @see http://stackoverflow.com/a/11949899/230513
 */
public class Test {

    private static final int N = 128;
    private static final Random random = new Random();
    private int n = 1;

    private void display() {
        JFrame f = new JFrame("TabChart");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel p = new JPanel(new GridLayout(0, 1));
        for (int i = 0; i < 3; i++) {
            p.add(createPane());
        }
        f.add(p, BorderLayout.CENTER);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private ChartPanel createPane() {
        final XYSeries series = new XYSeries("Data");
        for (int i = 0; i < random.nextInt(N) + N / 2; i++) {
            series.add(i, random.nextGaussian());
        }
        XYSeriesCollection dataset = new XYSeriesCollection(series);
        new Timer(500, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                series.add(series.getItemCount(), random.nextGaussian());
            }
        }).start();
        JFreeChart chart = ChartFactory.createXYLineChart("Test", "Domain",
            "Range", dataset, PlotOrientation.VERTICAL, false, false, false);
        return new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(480, 240);
            }
        };
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().display();
            }
        });
    }
}

这篇关于每 500 毫秒平滑渲染 Swing 组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆