【问题标题】:How to insert a JFreeChart chart in a panel on a separate GUI?如何在单独的 GUI 的面板中插入 JFreeChart 图表?
【发布时间】:2016-04-20 18:55:27
【问题描述】:

我想使用 JFreeChart 在 GUI 中的特定面板中放置一个图表。我有 2 个 java 文件(一个带有 GUI,另一个创建图形),如果可能的话,希望保持这种方式。

在主 GUI 中,我有一个名为 panelGraph 的面板:

    JPanel panelGraph = new JPanel();
    panelGraph.setBounds(220, 64, 329, 250);
    panelMain.add(panelGraph); //it is inside the main panel
    panelGraph.setLayout(null);

而且我还有一个按钮可以触发图表的出现:

    Button btnGetGraph = new JButton("Draw Graph");
    btnGetGraph.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

            XYLineChart_AWT.runGraph("Cenas", "Titulo", "XLABEL", "YLABEL", panelGraph);

        }
    });
    btnGetGraph.setFont(new Font("Tahoma", Font.BOLD, 13));
    btnGetGraph.setBounds(323, 327, 128, 34);
    panelMain.add(btnGetGraph);

如下,是创建图的java文件:

  public class XYLineChart_AWT extends JFrame {
  public XYLineChart_AWT( String applicationTitle, String chartTitle, String xLabel, String yLabel, JPanel panel) {

  JFreeChart xylineChart = ChartFactory.createXYLineChart(
     chartTitle ,
     xLabel ,
     yLabel ,
     createDataset() ,
     PlotOrientation.VERTICAL ,
     true , false , false);

  ChartPanel chartPanel = new ChartPanel( xylineChart );
  chartPanel.setPreferredSize( panel.getSize() );


  final XYPlot plot = xylineChart.getXYPlot( );
  plot.setBackgroundPaint(new Color(240, 240, 240));
  XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true,false);
  renderer.setSeriesPaint( 0 , Color.BLACK );
  renderer.setSeriesStroke( 0 , new BasicStroke( 4.0f ) );
  plot.setRenderer( renderer );
  setContentPane(chartPanel);
  panel.add(chartPanel);
  }

private XYDataset createDataset( ){

  final XYSeries seno = new XYSeries ("Sin");
  for(double i=0;i<=1440;i++){
      double temp=Math.sin(i*((2*Math.PI)/640) + Math.PI) + 1;
      seno.add(i/60, temp);
  }


  final XYSeriesCollection dataset = new XYSeriesCollection( );          
  dataset.addSeries(seno);
  return dataset;
}

public static void runGraph(String appTitle, String chartTitle, String xLabel, String yLabel, JPanel panel) {
  XYLineChart_AWT chart = new XYLineChart_AWT(appTitle, chartTitle, xLabel, yLabel, panel);

  chart.pack();
  chart.setVisible(true);
  panel.setVisible(true);

 }
}

这将创建图形并将其放入指定的面板(我通过 runGraph() 方法发送)。 但是,它会创建一个我不想在我发送的面板之外创建的第二个 JFrame(我知道我制作了 chart.setVisible(true),我可以将其设置为 false)。

有什么方法可以实现不创建额外的 jFrame 吗?

P.S.:另一个问题:setBackgroundPaint() 方法改变了图表显示的背面。但是标题和图例所在的部分不会改变。我怎样才能改变那些部分?

感谢您的帮助,

尼卡斯

【问题讨论】:

    标签: java swing user-interface jfreechart


    【解决方案1】:

    不要使用XYLineChartAWT 构造函数来实例化ChartPanel,而是将runGraph() 设为返回JFreeChart 的工厂方法,以便在主GUI 的ChartPanel 中使用。使用图表面板方法setChart(),它将自动更新您的面板。要更改图表面板的默认大小,请覆盖 getPreferredSize(),如 here 所示。

    import java.awt.BasicStroke;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import javax.swing.AbstractAction;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    
    /**
     * @see https://stackoverflow.com/a/36757609/230513
     */
    public class Test {
    
        private void display() {
            JFrame f = new JFrame("Test");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            final ChartPanel chartPanel = new ChartPanel(null);
            f.add(chartPanel);
            f.add(new JButton(new AbstractAction("Draw Graph") {
                @Override
                public void actionPerformed(ActionEvent e) {
                    chartPanel.setChart(
                        new XYLineChartAWT().runGraph("Title", "X", "Y"));
                }
            }), BorderLayout.SOUTH);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Test()::display);
        }
    }
    
    public class XYLineChartAWT {
    
        public JFreeChart runGraph(String chartTitle, String xLabel, String yLabel) {
            JFreeChart xylineChart = ChartFactory.createXYLineChart(
                chartTitle,
                xLabel,
                yLabel,
                createDataset(),
                PlotOrientation.VERTICAL,
                true, false, false);
            final XYPlot plot = xylineChart.getXYPlot();
            plot.setBackgroundPaint(new Color(240, 240, 240));
            XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false);
            renderer.setSeriesPaint(0, Color.BLACK);
            renderer.setSeriesStroke(0, new BasicStroke(4.0f));
            plot.setRenderer(renderer);
            return xylineChart;
        }
    
        private XYDataset createDataset() {
            final XYSeries seno = new XYSeries("Sin");
            for (double i = 0; i <= 1440; i++) {
                double temp = Math.sin(i * ((2 * Math.PI) / 640) + Math.PI) + 1;
                seno.add(i / 60, temp);
            }
            final XYSeriesCollection dataset = new XYSeriesCollection();
            dataset.addSeries(seno);
            return dataset;
        }
    }
    

    【讨论】:

    • 感谢您的意见。我今天晚些时候会试试这个,我会带着正确的答复回来。感谢您的回答!
    • 为了让它正常工作,我确实在为图表创建的 chartPanel 上使用了 .setBounds() 方法。但是,对于我在网上阅读的内容,这不是最好的做法。我应该使用 LayoutManagers,对吗?您推荐使用哪一种?提前致谢
    • @Nhekas:我同意避免使用setBounds()JFrame的默认布局是BorderLayout,默认目的地是CENTER,上面例子中隐含了; GridLayout,见于here,还允许图表在调整框架大小时进行调整。
    • 好的,我会试试那个布局。另一个不相关的问题:创建主框架时,我应该如何创建它?如果我使用 pack() 方法,即使我有多个组件,它也会开始非常小。是不是因为当前设置为空(绝对)布局?
    • 对;也覆盖getPreferredSize() 所以pack() 会知道面板应该有多大。
    【解决方案2】:

    我想建议使用 Nice Application 1,Jfree 修改后的 jar 可以从 NiceApplication1.BlogSpot.Com 下载。转到博客并下载新的 Nice Application 1 Home Stupendous,然后解压后,将文件夹转到 dist 文件夹并打开 Java Jar Nice Application 1,这样您将获得一个修改后的 jar jfree_NiceApplication1,其中包含一个关于如何使用它的记事本文件罐子。

    提供了一个饼图示例。

    jar 后只需要键入方法-

    字符串 ao1 = a1.getText(); 字符串 ao2 = a2.getText();

    DefaultPieDataset pieDataset = new DefaultPieDataset();

        pieDataset.setValue("earn", new Double(ao1));
        pieDataset.setValue("Allbilltotal", new Double(ao2));
    

    //注意 pieDataset & ch 将是你的变量。

    JFreeChart ch = ChartFactory.createPieChart3D("Test", pieDataset, true, true, true);

        PiePlot3D p = (PiePlot3D) ch.getPlot();
    

    // 导入 o​​rg.jfree.chart.Nice_Application_1_JPanel;

        Nice_Application_1_JPanel pant = new Nice_Application_1_JPanel(pieDataset);  
        pieDataset = pant.pieDataset;
        pant.PanelApplication1 = jPanel;   
        pant.size = new java.awt.Dimension(200, 200);
        pant.Nice_Application1(ch);
    

    StandardChartTheme 主题 = new StandardChartTheme(ch.toString());

    theme.setTitlePaint( Color.decode( "#4572a7" ) );
    theme.setRangeGridlinePaint( Color.decode("#C0C0C0"));
    theme.setPlotBackgroundPaint( Color.blue );
    theme.setChartBackgroundPaint( Color.BLACK );
    theme.setGridBandPaint( Color.red );
    theme.setBarPainter(new StandardBarPainter());
    theme.setAxisLabelPaint( Color.decode("#666666")  );
    

    theme.apply(ch);


    对于折线图也可以键入相同的,图表面板类型的地方只有- // 导入 o​​rg.jfree.chart.Nice_Application_1_JPanel;

        Nice_Application_1_JPanel pant = new Nice_Application_1_JPanel(pieDataset);  
        pieDataset = pant.pieDataset;
        pant.PanelApplication1 = jPanel;   
        pant.size = new java.awt.Dimension(200, 200);
        pant.Nice_Application1(ch);
    

    【讨论】:

    • 感谢小伙伴的回复!
    猜你喜欢
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    相关资源
    最近更新 更多