【问题标题】:Rendering Swing component smoothly every 500 millisecond每 500 毫秒平滑渲染 Swing 组件
【发布时间】:2023-08-18 15:51:01
【问题描述】:

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

Rendering with error and 我怎么解决这个问题?

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

此代码每 500 毫秒调用一次,ChartUpdate(MyObject, Panel) 是使用MyObject 的信息在Panel 上构建图表的功能。

【问题讨论】:

  • 闪烁是什么意思?
  • JTabbedPane(doubleBuffered) 使用 PaintComponent() 重新绘制,这会导致闪烁(我最近发现)。重绘时也是如此。它重新绘制错误。我怎样才能不出错地重新粉刷。
  • 一个相关问题:我们如何在没有相关代码的情况下帮助识别导致您的问题的问题?请创建并发布您的minimal reproducible examplesscce
  • paintComponents(Tabb.getGraphics());这不是自定义绘画的方法!有关详细信息,请参阅Performing Custom Painting。一般提示: 1) 为了尽快获得更好的帮助,请发帖 minimal reproducible exampleShort, Self Contained, Correct Example。 2) 请学习常见的 Java 命名法(命名约定 - 例如EachWordUpperCaseClassfirstWordLowerCaseMethod()firstWordLowerCaseAttribute,除非它是 UPPER_CASE_CONSTANT)并始终如一地使用它。
  • FirstChart.removeAll(); .. FirstChart.add(Label1); 可能有比删除和添加组件更好的方法。一旦您发布了 MCVE/SSCCE,就会知道这种方法是什么。

标签: java swing charts rendering jfreechart


【解决方案1】:

不要替换视图组件。相反,更新相应的模型,监听视图将更新自身作为响应。在下面的示例中,createPane() 返回的每个 ChartPanel 都有一个 Swing Timer,它每 500 毫秒更新一次 XYSeries

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://*.com/a/38512314/230513
 * @see http://*.com/a/15715096/230513
 * @see http://*.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();
            }
        });
    }
}

【讨论】:

  • 谢谢大家的精彩回答。我得到了所有的变化。爱你们。