问题描述
我想使用JFreeChart将图表放在GUI中的特定面板中。我有2个java文件(一个用于GUI,另一个用于创建图形),并且如果可能的话,希望保持这种方式。
在主GUI中我有一个名为panelGraph的面板:
JPanel panelGraph = new JPanel();
panelGraph.setBounds(220,64,329,250);
panelMain.add(panelGraph); //它在主面板内
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文件:
公共类XYLineChart_AWT扩展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,虚假,虚假);
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);
返回数据集;
}
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?
PS:另一个问题:setBackgroundPaint( )方法改变图形显示的背面。但是标题和图例的部分不会改变。我该如何更改这些部件?
感谢您的帮助,
Nhekas
而不是使用 XYLineChartAWT
构造函数来实例化 ChartPanel
,make runGraph()
返回 JFreeChart
的工厂方法,用于主GUI的 ChartPanel
。使用图表面板方法 setChart()
,它将自动更新您的面板。要更改图表面板的默认大小,请覆盖 getPreferredSize()
,如
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
* /
公共类测试{
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);
}
}
公共类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);
返回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);
返回数据集;
}
}
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
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.
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;
}
}
这篇关于如何在单独的GUI上的面板中插入JFreeChart图表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!