在单击之前无法加载从 JFreeChart 加载图表的线程
Cannot load a thread that loads chart from JFreeChart until clicked
我认为我做的一切都是对的。我想要的只是在加载组件的主线程和 window 完成后加载包含图表的线程。但它没有用。我必须以某种方式单击 jPanel1
(将加载图表的面板)并加载图表。任何帮助,将不胜感激。我尝试过的:
- 将线程更改为
SwingWorker
- 正在将主题更改为
invokeLater
public LaporanPenjualan() {
initComponents();
createFrame1();
}
private void createFrame1() {
SwingWorker thread = new SwingWorker() {
@Override
protected Boolean doInBackground() throws Exception {
JLabel loading = new JLabel("Loading, please wait",SwingConstants.CENTER);
loading.setSize(500,500);
loading.setAlignmentY(250);
jPanel1.add(loading);
final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(34.0, "Penjualan/produk", "Kue Enak");
dataset.addValue(23.0, "Penjualan/produk", "Kue Enggak Enak");
dataset.addValue(54.0, "Penjualan/produk", "Kue Sultan");
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setSize(500,500);
chartPanel.setPreferredSize(new Dimension(300, 300));
jPanel1.removeAll();
jPanel1.add(chartPanel);
chartPanel.setVisible(true);
return true;
}
};
thread.execute();
}
Swing 是单线程的,不是线程安全的。这意味着您不应该在事件调度线程的上下文中执行任何长 运行 或阻塞操作,并且您不应该修改 UI 的状态或 UI 的任何状态依赖于,来自 EDT 的上下文。
所以,话虽如此,您 createFrame1
可能看起来更像...
private void createFrame1() {
JLabel loading = new JLabel("Loading, please wait", SwingConstants.CENTER);
loading.setSize(500, 500);
loading.setAlignmentY(250);
jPanel1.add(loading);
jPanel1.revalidate();
jPanel1.repaint();
SwingWorker<DefaultCategoryDataset, Void> thread;
thread = new SwingWorker<>() {
@Override
protected DefaultCategoryDataset doInBackground() throws Exception {
final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(34.0, "Penjualan/produk", "Kue Enak");
dataset.addValue(23.0, "Penjualan/produk", "Kue Enggak Enak");
dataset.addValue(54.0, "Penjualan/produk", "Kue Sultan");
return dataset;
}
@Override
protected void done() {
try {
DefaultCategoryDataset dataset = get();
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
jPanel1.removeAll();
jPanel1.add(chartPanel);
chartPanel.setVisible(true);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
thread.execute();
}
或者,如果加载数据需要时间,您可以发布每个数据点...
public class DataPoint {
private double value;
private Comparable rowKey;
private Comparable columnKey;
public DataPoint(double value, Comparable rowKey, Comparable columnKey) {
this.value = value;
this.rowKey = rowKey;
this.columnKey = columnKey;
}
public double getValue() {
return value;
}
public Comparable getRowKey() {
return rowKey;
}
public Comparable getColumnKey() {
return columnKey;
}
}
private void createFrame1() {
SwingWorker<Void, DataPoint> thread;
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataSet,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
jPanel1.add(chartPanel);
thread = new SwingWorker<>() {
@Override
protected Void doInBackground() throws Exception {
publish(new DataPoint(34.0, "Penjualan/produk", "Kue Enak"));
publish(new DataPoint(23.0, "Penjualan/produk", "Kue Enggak Enak"));
publish(new DataPoint(54.0, "Penjualan/produk", "Kue Sultan"));
}
@Override
protected void process(List<DataPoint> chunks) {
for (DataPoint dp : chunks) {
dataSet.addValue(dp.getValue(), dp.getRowKey(), dp.getColumnKey());
}
}
};
thread.execute();
}
可运行示例...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataSet,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
add(chartPanel);
ChartWorker worker = new ChartWorker(dataSet);
worker.execute();
}
}
public class ChartWorker extends SwingWorker<Void, ChartWorker.DataPoint> {
public class DataPoint {
private double value;
private Comparable rowKey;
private Comparable columnKey;
public DataPoint(double value, Comparable rowKey, Comparable columnKey) {
this.value = value;
this.rowKey = rowKey;
this.columnKey = columnKey;
}
public double getValue() {
return value;
}
public Comparable getRowKey() {
return rowKey;
}
public Comparable getColumnKey() {
return columnKey;
}
}
private DefaultCategoryDataset dataSet;
public ChartWorker(DefaultCategoryDataset dataSet) {
this.dataSet = dataSet;
}
@Override
protected Void doInBackground() throws Exception {
// The sleeps here are just for demonstration,
// you don't need them
Thread.sleep(1000);
publish(new DataPoint(34.0, "Penjualan/produk", "Kue Enak"));
Thread.sleep(1000);
publish(new DataPoint(23.0, "Penjualan/produk", "Kue Enggak Enak"));
Thread.sleep(1000);
publish(new DataPoint(54.0, "Penjualan/produk", "Kue Sultan"));
return null;
}
@Override
protected void process(List<DataPoint> chunks) {
for (DataPoint dp : chunks) {
dataSet.addValue(dp.getValue(), dp.getRowKey(), dp.getColumnKey());
}
}
}
}
等待事情完成...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
add(new JLabel("Loading stuff", JLabel.CENTER));
ChartWorker worker = new ChartWorker();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())) {
if (worker.getState() == SwingWorker.StateValue.DONE) {
try {
DefaultCategoryDataset dataSet = worker.get();
setDataSet(dataSet);
} catch (InterruptedException ex) {
add(new JLabel("Loading fauked", JLabel.CENTER));
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
add(new JLabel("Loading fauked", JLabel.CENTER));
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
});
worker.execute();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected void setDataSet(DefaultCategoryDataset dataSet) {
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataSet,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
removeAll();
add(chartPanel);
revalidate();
repaint();
}
}
public class ChartWorker extends SwingWorker<DefaultCategoryDataset, Void> {
public ChartWorker() {
}
@Override
protected DefaultCategoryDataset doInBackground() throws Exception {
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
dataSet.addValue(34.0, "Penjualan/produk", "Kue Enak");
dataSet.addValue(23.0, "Penjualan/produk", "Kue Enggak Enak");
dataSet.addValue(54.0, "Penjualan/produk", "Kue Sultan");
// Again, you don't need this
Thread.sleep(5000);
return dataSet;
}
}
}
我认为我做的一切都是对的。我想要的只是在加载组件的主线程和 window 完成后加载包含图表的线程。但它没有用。我必须以某种方式单击 jPanel1
(将加载图表的面板)并加载图表。任何帮助,将不胜感激。我尝试过的:
- 将线程更改为
SwingWorker
- 正在将主题更改为
invokeLater
public LaporanPenjualan() {
initComponents();
createFrame1();
}
private void createFrame1() {
SwingWorker thread = new SwingWorker() {
@Override
protected Boolean doInBackground() throws Exception {
JLabel loading = new JLabel("Loading, please wait",SwingConstants.CENTER);
loading.setSize(500,500);
loading.setAlignmentY(250);
jPanel1.add(loading);
final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(34.0, "Penjualan/produk", "Kue Enak");
dataset.addValue(23.0, "Penjualan/produk", "Kue Enggak Enak");
dataset.addValue(54.0, "Penjualan/produk", "Kue Sultan");
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setSize(500,500);
chartPanel.setPreferredSize(new Dimension(300, 300));
jPanel1.removeAll();
jPanel1.add(chartPanel);
chartPanel.setVisible(true);
return true;
}
};
thread.execute();
}
Swing 是单线程的,不是线程安全的。这意味着您不应该在事件调度线程的上下文中执行任何长 运行 或阻塞操作,并且您不应该修改 UI 的状态或 UI 的任何状态依赖于,来自 EDT 的上下文。
所以,话虽如此,您 createFrame1
可能看起来更像...
private void createFrame1() {
JLabel loading = new JLabel("Loading, please wait", SwingConstants.CENTER);
loading.setSize(500, 500);
loading.setAlignmentY(250);
jPanel1.add(loading);
jPanel1.revalidate();
jPanel1.repaint();
SwingWorker<DefaultCategoryDataset, Void> thread;
thread = new SwingWorker<>() {
@Override
protected DefaultCategoryDataset doInBackground() throws Exception {
final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(34.0, "Penjualan/produk", "Kue Enak");
dataset.addValue(23.0, "Penjualan/produk", "Kue Enggak Enak");
dataset.addValue(54.0, "Penjualan/produk", "Kue Sultan");
return dataset;
}
@Override
protected void done() {
try {
DefaultCategoryDataset dataset = get();
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
jPanel1.removeAll();
jPanel1.add(chartPanel);
chartPanel.setVisible(true);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
thread.execute();
}
或者,如果加载数据需要时间,您可以发布每个数据点...
public class DataPoint {
private double value;
private Comparable rowKey;
private Comparable columnKey;
public DataPoint(double value, Comparable rowKey, Comparable columnKey) {
this.value = value;
this.rowKey = rowKey;
this.columnKey = columnKey;
}
public double getValue() {
return value;
}
public Comparable getRowKey() {
return rowKey;
}
public Comparable getColumnKey() {
return columnKey;
}
}
private void createFrame1() {
SwingWorker<Void, DataPoint> thread;
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataSet,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
jPanel1.add(chartPanel);
thread = new SwingWorker<>() {
@Override
protected Void doInBackground() throws Exception {
publish(new DataPoint(34.0, "Penjualan/produk", "Kue Enak"));
publish(new DataPoint(23.0, "Penjualan/produk", "Kue Enggak Enak"));
publish(new DataPoint(54.0, "Penjualan/produk", "Kue Sultan"));
}
@Override
protected void process(List<DataPoint> chunks) {
for (DataPoint dp : chunks) {
dataSet.addValue(dp.getValue(), dp.getRowKey(), dp.getColumnKey());
}
}
};
thread.execute();
}
可运行示例...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataSet,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
add(chartPanel);
ChartWorker worker = new ChartWorker(dataSet);
worker.execute();
}
}
public class ChartWorker extends SwingWorker<Void, ChartWorker.DataPoint> {
public class DataPoint {
private double value;
private Comparable rowKey;
private Comparable columnKey;
public DataPoint(double value, Comparable rowKey, Comparable columnKey) {
this.value = value;
this.rowKey = rowKey;
this.columnKey = columnKey;
}
public double getValue() {
return value;
}
public Comparable getRowKey() {
return rowKey;
}
public Comparable getColumnKey() {
return columnKey;
}
}
private DefaultCategoryDataset dataSet;
public ChartWorker(DefaultCategoryDataset dataSet) {
this.dataSet = dataSet;
}
@Override
protected Void doInBackground() throws Exception {
// The sleeps here are just for demonstration,
// you don't need them
Thread.sleep(1000);
publish(new DataPoint(34.0, "Penjualan/produk", "Kue Enak"));
Thread.sleep(1000);
publish(new DataPoint(23.0, "Penjualan/produk", "Kue Enggak Enak"));
Thread.sleep(1000);
publish(new DataPoint(54.0, "Penjualan/produk", "Kue Sultan"));
return null;
}
@Override
protected void process(List<DataPoint> chunks) {
for (DataPoint dp : chunks) {
dataSet.addValue(dp.getValue(), dp.getRowKey(), dp.getColumnKey());
}
}
}
}
等待事情完成...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
add(new JLabel("Loading stuff", JLabel.CENTER));
ChartWorker worker = new ChartWorker();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())) {
if (worker.getState() == SwingWorker.StateValue.DONE) {
try {
DefaultCategoryDataset dataSet = worker.get();
setDataSet(dataSet);
} catch (InterruptedException ex) {
add(new JLabel("Loading fauked", JLabel.CENTER));
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
add(new JLabel("Loading fauked", JLabel.CENTER));
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
});
worker.execute();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected void setDataSet(DefaultCategoryDataset dataSet) {
final JFreeChart chart = ChartFactory.createBarChart(
"",
"Produk",
"Penjualan",
dataSet,
PlotOrientation.VERTICAL,
true,
true,
false
);
final ChartPanel chartPanel = new ChartPanel(chart);
removeAll();
add(chartPanel);
revalidate();
repaint();
}
}
public class ChartWorker extends SwingWorker<DefaultCategoryDataset, Void> {
public ChartWorker() {
}
@Override
protected DefaultCategoryDataset doInBackground() throws Exception {
DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
dataSet.addValue(34.0, "Penjualan/produk", "Kue Enak");
dataSet.addValue(23.0, "Penjualan/produk", "Kue Enggak Enak");
dataSet.addValue(54.0, "Penjualan/produk", "Kue Sultan");
// Again, you don't need this
Thread.sleep(5000);
return dataSet;
}
}
}