【问题标题】:JFreeChart MeterPlotJFreeChart MeterPlot
【发布时间】:2013-11-18 20:42:48
【问题描述】:

我目前正在用 java 做代理项目。在某些时候,我需要显示一个仪表,例如:电池电量。我的程序中有 5 个代理,每个代理创建自己的仪表图,上面有名称,但不知何故他们没有更新数据集。或者他们正在更新数据集,只是它没有显示在仪表图上。有什么想法吗?

以下是我的代码: car.java

{
    private CarMeter meter;
    meter = new CarMeter(getLocalName());
    meter.update(currentBatteryCharge);
}

meterplot.java

public class CarMeter extends ApplicationFrame {

 private static DefaultValueDataset dataset1;

public CarMeter(String s) {
    super(s);
    JPanel panel = createPanel();
    panel.setPreferredSize(new Dimension(500, 350));
    setContentPane(panel);
    pack();
    setVisible(true);
}

public CarMeter() {
    super("s");
    JPanel panel = createPanel();
    panel.setPreferredSize(new Dimension(500, 350));
    setContentPane(panel);
    pack();
    setVisible(true);
}

private static JFreeChart createChart(ValueDataset valuedataset) {
    MeterPlot meterplot = new MeterPlot(valuedataset);
  //set minimum and maximum value
    meterplot.setRange(new Range(0.0D, 100000D));

    meterplot.addInterval(new MeterInterval("Battery LOW", new Range(0.0D, 10000D), 
            Color.red, new BasicStroke(2.0F), new Color(255, 0, 0, 128)));

    meterplot.addInterval(new MeterInterval("Moderate", new Range(10001D, 90000D), 
            Color.yellow, new BasicStroke(2.0F), new Color(255, 255, 0, 64)));

    meterplot.addInterval(new MeterInterval("Battery FULL", new Range(90001D, 100000D),
            Color.green, new BasicStroke(2.0F), new Color(0, 255, 0, 64)));

    meterplot.setNeedlePaint(Color.darkGray);
    meterplot.setDialBackgroundPaint(Color.white);
    meterplot.setDialOutlinePaint(Color.black);
    meterplot.setDialShape(DialShape.CHORD);
    meterplot.setMeterAngle(180);
    meterplot.setTickLabelsVisible(true);
    meterplot.setTickLabelFont(new Font("Arial", 1, 12));
    meterplot.setTickLabelPaint(Color.black);
    meterplot.setTickSize(5D);
    meterplot.setTickPaint(Color.gray);
    meterplot.setValuePaint(Color.black);
    meterplot.setValueFont(new Font("Arial", 1, 14));
    JFreeChart jfreechart = new JFreeChart("Battery Level",
            JFreeChart.DEFAULT_TITLE_FONT, meterplot, true);
    return jfreechart;
}

public static JPanel createPanel() {
    dataset1 = new DefaultValueDataset(0);
    JFreeChart chart = createChart(dataset1);
    ChartPanel chartpanel = new ChartPanel(chart);
    return chartpanel;
}

public void update(int data){
dataset1.setValue(data);
System.out.println(""+dataset1 +" " +data);
}

【问题讨论】:

  • 我试过你的代码,它可以工作。 update 方法对我有用。你有什么问题?
  • 我有一个创建 5 car.java 的初始化程序。他们每个人都有自己的计量图。 name : Car 1 , Car 2.. etc. 假设 5 个地块应根据股票代码更新。但它不会更新所有情节。它只更新即:汽车 2 米图。其余为 0。

标签: java swing jfreechart


【解决方案1】:

正如@alex2410 所述,您的代码如下所示。正如@Outlaw 引用的answer 中所述,绘图(视图)监听数据集(模型)。一些笔记,

  • 不要在构造函数中重复代码;让一个调用另一个。

  • 当你真的想覆盖getPreferredSize()时,不要使用setPreferredSize()

  • 不要使用静态成员来引用可重用视图类中的模型。

  • 不要在构造函数中调用公共方法。

  • 请使用连续范围以避免标签中出现视觉伪影。

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.DialShape;
import org.jfree.chart.plot.MeterInterval;
import org.jfree.chart.plot.MeterPlot;
import org.jfree.data.Range;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.data.general.ValueDataset;
import org.jfree.ui.ApplicationFrame;

public class CarMeter extends ApplicationFrame {

    private DefaultValueDataset dataset;
    private int value = 50000;

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

    public CarMeter(String s) {
        super(s);
        JPanel panel = createPanel();
        setContentPane(panel);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        Timer t = new Timer(250, new ActionListener() {
            Random r = new Random();

            @Override
            public void actionPerformed(ActionEvent e) {
                value -= (int) (Math.abs(100 * r.nextGaussian()));
                update(value);
            }
        });
        t.start();
    }

    public CarMeter() {
        this("Test");
    }

    private JFreeChart createChart(ValueDataset valuedataset) {
        MeterPlot meterplot = new MeterPlot(valuedataset);
        meterplot.setRange(new Range(0.0D, 100000D));
        meterplot.addInterval(new MeterInterval("Battery LOW", new Range(0.0D, 10000D),
            Color.red, new BasicStroke(2.0F), new Color(255, 0, 0, 128)));
        meterplot.addInterval(new MeterInterval("Moderate", new Range(10000D, 90000D),
            Color.yellow, new BasicStroke(2.0F), new Color(255, 255, 0, 64)));
        meterplot.addInterval(new MeterInterval("Battery FULL", new Range(90000D, 100000D),
            Color.green, new BasicStroke(2.0F), new Color(0, 255, 0, 64)));

        meterplot.setNeedlePaint(Color.darkGray);
        meterplot.setDialBackgroundPaint(Color.white);
        meterplot.setDialOutlinePaint(Color.black);
        meterplot.setDialShape(DialShape.CHORD);
        meterplot.setMeterAngle(180);
        meterplot.setTickLabelsVisible(true);
        meterplot.setTickLabelFont(new Font("Arial", 1, 14));
        meterplot.setTickLabelPaint(Color.black);
        meterplot.setTickSize(5D);
        meterplot.setTickPaint(Color.gray);
        meterplot.setValuePaint(Color.black);
        meterplot.setValueFont(new Font("Arial", 1, 14));
        JFreeChart jfreechart = new JFreeChart("Battery Level",
            JFreeChart.DEFAULT_TITLE_FONT, meterplot, true);
        return jfreechart;
    }

    private JPanel createPanel() {
        dataset = new DefaultValueDataset(value);
        JFreeChart chart = createChart(dataset);
        ChartPanel chartpanel = new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(640, 480);
            }
        };
        return chartpanel;
    }

    public void update(int data) {
        dataset.setValue(data);

    }
}

【讨论】:

  • 您好,感谢您的建议。这是更明显的事情。如果我在 main.js 中添加另一个新的 CarMeter。两者都开始更新。将显示 2 米图,但只有 1 米会更新。公共静态无效主(字符串args []){ CarMeter boo = new CarMeter(“boo”); CarMeter foo = new CarMeter("foo"); for(int i = 0 ; i
  • 我对静态模型或多帧持谨慎态度;请编辑您的问题以包含一个sscce,以显示您当前的方法。
  • 我已经尝试过@trashgod 的示例,对其进行了修改,我在一个JFrame 中添加了5 个图表,并在SwingTimer 的帮助下对其进行了更新,它工作正常。看看这个例子,它回答了你的问题。如果您不这么认为,请发布您的代码,在其中创建所有仪表并尝试更新它们。
【解决方案2】:

认为这是与Jfreechart - Refresh a chart according to changing data的重复

您需要以某种方式重新绘制图表,更新方法只会设置数据值,而图表本身保持不变。

为了快速而肮脏的修复,无需进一步研究,我建议再次调用 createChart 方法(在您的更新方法内)并更新图表对象。

只是为了验证这是否能解决问题。我建议您阅读 GOF 观察者模式,这是一种将 GUI 与数据分离并在需要时更新 GUI http://en.wikipedia.org/wiki/Observer_pattern 的好方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多