dgteixeira
dgteixeira

Reputation: 61

How to insert a JFreeChart chart in a panel on a separate GUI?

I want to put a chart inside a specific panel in a GUI using JFreeChart. I have 2 java files (one with the GUI, and another that creates the graph) and would like , if possible, to keep it this way.

In the main GUI I have a panel called panelGraph:

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

And I also have a button that triggers the appearance of the graph:

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

And as follows, is the java file that creates the graph:

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

 }
}

This creates the graph and puts it into the specified panel (that I send through the method runGraph()). However, it creates a 2nd JFrame ( I know i made chart.setVisible(true) and I can just put it to false) that I don't want to be created outside of the panel I send.

Is there any way to implement this that does not create that extra jFrame?

P.S.: Another question: the setBackgroundPaint() method changes the back of where the graph is shown. However the parts where the title and legend are don't change. How can I change those parts?

Thank you for your help,

Nhekas

Upvotes: 2

Views: 2392

Answers (2)

Alan
Alan

Reputation: 9

I want to suggest use Nice Application 1 the Jfree modified jar can download from NiceApplication1.BlogSpot.Com. Go to the blog and Download new Nice Application 1 Home Stupendous, then after extract, the folder go to the dist folder and open the Java Jar Nice Application 1, so you will get a modified jar jfree_NiceApplication1 with a notepad file about how can use that jar.

A pie chart example is available.

After jar only need to type method-

String ao1 = a1.getText(); String ao2 = a2.getText();

DefaultPieDataset pieDataset = new DefaultPieDataset();

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

//Note pieDataset & ch will be your variable.

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

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

// import org.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 theme = 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 );


For line chart also can type the same, the place of the Chart panel type only- // import org.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);

Upvotes: 1

trashgod
trashgod

Reputation: 205765

Instead of using the XYLineChartAWT constructor to instantiate a ChartPanel, make runGraph() a factory method that returns a JFreeChart for use in your main GUI's ChartPanel. Use the chart panel method setChart(), which will update your panel automatically. To change the chart panel's default size, override getPreferredSize() as shown here.

image

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

Upvotes: 2

Related Questions