1
我一直在試驗JFreeChart以獲得即將推出的項目,並查看它們看起來相當直接的教程。我創建了一個簡單的小程序,要求輸入一些數據並顯示一個3D餅圖。它可以工作,但是在面板中顯示圖表時只能部分顯示圖表。如果您在面板內單擊,則它將增長到顯示面板的大小。我試過在不同的地方設置各種setPreferredSize(),但似乎沒有任何工作。我錯過了什麼?Java JFreeChart在JPanel中沒有完全顯示圖表
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.Rectangle;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.JButton;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.util.Rotation;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
public class mWindow extends JFrame{
private JPanel pnlDisplay;
private JPanel panel;
private JLabel label_1;
private JLabel label_2;
private JSpinner spinner;
private JButton button;
/**
* Window Constructor
*/
private mWindow(){
setBounds(new Rectangle(0, 0, 600, 500));
getContentPane().setLayout(new MigLayout("", "[200px:200.00][564px,grow]", "[120px:120.00][308px,grow]"));
panel = new JPanel();
panel.setLayout(null);
panel.setBorder(new EtchedBorder(EtchedBorder.RAISED, null, null));
getContentPane().add(panel, "cell 0 0,grow");
label_1 = new JLabel("Control Panel");
label_1.setBounds(10, 10, 100, 20);
panel.add(label_1);
label_2 = new JLabel("Number of Values");
label_2.setBounds(10, 40, 100, 20);
panel.add(label_2);
spinner = new JSpinner();
spinner.setBounds(120, 40, 40, 20);
panel.add(spinner);
button = new JButton("Create Pie Chart");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
createPieChart();
}
});
button.setBounds(10, 70, 150, 40);
panel.add(button);
pnlDisplay = new JPanel();
pnlDisplay.setBorder(new EtchedBorder(EtchedBorder.RAISED, null, null));
getContentPane().add(pnlDisplay, "cell 0 1 2 1,grow");
pnlDisplay.setLayout(null);
}
private void createPieChart(){
// create the data set
// create the chart
// put chart in a panel
// set default configuration for panel
// add panel to our displayPanel
int numVal = (int) spinner.getValue();
JTextField label = new JTextField();
JTextField value = new JTextField();
DefaultPieDataset dds = new DefaultPieDataset();
final JComponent[] fieldInput = new JComponent[]{
new JLabel("Label Name"), label,
new JLabel("Value"), value
};
for(int index = 0; index < numVal; index++){
// Display a dialog asking for the Information Needed to add a job
int n = JOptionPane.showConfirmDialog(
this,
fieldInput,
"Create Data Set " + (index+1),
JOptionPane.PLAIN_MESSAGE
);
if(n < 0){
JOptionPane.showMessageDialog(this, "No Data Set has been created",
"Data Set Add Canceled ", JOptionPane.ERROR_MESSAGE);
return;
}
String Label = label.getText();
int Value = Integer.parseInt(value.getText());
dds.setValue(Label, Value);
label.setText("");
value.setText("");
}
// Data set ready ~ create the chart
JFreeChart chart = ChartFactory.createPieChart3D("Our Pie Chart", // chart title
dds, // data set
true, // include legend
true, // enable tool tips
false); // use urls
PiePlot3D plot = (PiePlot3D) chart.getPlot();
plot.setStartAngle(290); // angel of first data set
plot.setDirection(Rotation.CLOCKWISE); // rotation of chart
plot.setForegroundAlpha(0.2f); // set alpha transparency
// create a panel to track chart changes and set it's default size
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(pnlDisplay.getSize());
chartPanel.setBounds(10,10,pnlDisplay.getWidth()-20,pnlDisplay.getHeight()-20);
// add our chart to our display panel
pnlDisplay.add(chartPanel);
pnlDisplay.validate();
}
/**
* Initializes and Show the GUI
*/
private static void InitalizeAndShowGUI(){
mWindow mainWindow = new mWindow();
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setTitle("Chart Demo v0.1");
Dimension windowSize = new Dimension(600,700);
mainWindow.setMinimumSize(windowSize);
mainWindow.setLocation(100, 100);
mainWindow.pack();
mainWindow.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
InitalizeAndShowGUI();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
我只是回來對我原先的評論。是的,你是正確的repaint()負責繪製一旦更新後的面板。我假設validate()或revalidate()更新模型,而repaint更新顯示。這是否是一個正確的假設? – jbolt
好吧,你不必擔心重繪在這裏,但作爲'pnlDisplay'具有空佈局,你必須管理重繪。 re/validate()管理組件的佈局,所以在這種情況下不要幫助你。 – Reimeus
謝謝我將在處理空佈局時記住這一點。 – jbolt