java jpanel 与 repaint() 同步或:是否可以将 Listener 添加到 swing 的重绘中?
java jpanel synchronization with repaint() or: Is a Listener addable to swing's repaint?
我正在为一个 miscropy 程序编写一个插件,但 repaint() 方法有问题。
小问题:
有没有什么方法可以在 JPanel 的重绘完成或与它同步代码后立即得到通知?
详细版本:
我的程序可以将 xy 图中的一组数据绘制到 JPanel 并使用 jfree.chart 显示它;在程序的另一部分,我有许多数据集(~100),我想绘制并保存为图像。我也找到了解决方案,但我真的不喜欢它。问题可以简化为有关 JPanel 的绘制状态的通知。
在保存所有图像的部分我有这个解决方案:
PlotSpectrum spectrumWindow = getTheWindow(); //pseudo code...
// some stuff
ti = storage.getImage(channel, slice, frame, position);
spectrumWindow.plotData(false, andor.captureSpectrum(ti.pix), wave,
centerWave, fineGrating, exposureTime,
slitWidth, substractBackground);
spectrumWindow.repaint(); // probably not necessary
sleep(100); // this annoys me...
spectrumWindow.savePlot(path, true, config, null);
spectrumWindow 是一个 JPanel,它也显示在另一个 window 中,并且一切正常。
但是我真的不喜欢那里的睡眠(100)......没有它我要求重新粉刷但是直到我尝试保存 "snapshot" 的(这就是 savePlot 正在做的)才完成...)。我知道,其他线程和这些该死的同步问题......
随着睡眠,我只是让它不必要地变慢,如果我等待的时间不够长,图像就不会完全绘制(例如,下半部分丢失)
有什么方法可以在重绘完成后立即得到通知吗?我可能对 Listener 也很好,更好的方法是使用监视器或类似的解决方案,或者现在正在重绘的方法(据我所知不存在?)
主 GUI(包括 JPanel spectrumWindow)和之前粘贴的代码在不同的线程中 运行。
我的代码中可能也很重要的部分如下。如果某些括号不匹配或某些变量未声明,请原谅,我删除了很多代码。
谢谢
schetefan24
class PlotSpectrum extends ApplicationFrame // that extends JFrame
{
public void plotData(boolean backgroundGiven, int[] spect, double[] wave_,
double centerWave, boolean fineGrating_, double exposureTime,
double slitWidth, boolean substractBackground)
{
//process data and store internally
replot();
}
private void replot()
{
XYSeries series = new XYSeries("Spectrum");
//add data to series
XYSeriesCollection collection = new XYSeriesCollection(series);
//setting up some labels and such stuff...
JFreeChart chart = ChartFactory.createXYLineChart(
title,
"Wavelength [nm]",
yLabel,
collection,
PlotOrientation.VERTICAL,
false,
false,
false
);
dataPanel.add(new ChartPanel(chart)); // this is contained in a Frame
}
public void savePlot(String path, boolean overWriteAll, HashMap<String,String> config, int[][] addData)
{
File output = new File(path);
//some more stuff, ask overwrite etc
if(image)
{
BufferedImage im = createImage();
String extension = path.substring(path.lastIndexOf(".")+1, path.length());
ImageIO.write(im, extension, output);
} else {
//that is an textexport, works fine
}
}
public BufferedImage createImage()
{
JPanel panel = (JPanel) flipChart.getSelectedComponent();
int w = panel.getWidth();
int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
return bi;
}
}
that I want to plot and save as images.
- 将数据添加到不可见面板。
- 创建一个
BufferedImage
的面板
- 使用上面的图像创建一个
ImageIcon
- 使用
setIcon(...)
方法 更新 JLabel
(已添加到框架中)
- 上述步骤应在图标更改时生成
PropertyChange
事件。您可以使用 ProperChangeListener
来监听这个事件。收到事件后,您可以重复步骤 1 - 4。
查看 Screen Image。它将帮助您创建不可见组件的图像。
请注意,您并不是真的需要步骤 4-5。我只是添加了它们,这样您就可以在处理它们时看到这些图。如果您不想要视觉效果,那么您可能只是在 JLabel 上显示文本,指示当前正在转换哪个图。
我正在为一个 miscropy 程序编写一个插件,但 repaint() 方法有问题。
小问题: 有没有什么方法可以在 JPanel 的重绘完成或与它同步代码后立即得到通知?
详细版本:
我的程序可以将 xy 图中的一组数据绘制到 JPanel 并使用 jfree.chart 显示它;在程序的另一部分,我有许多数据集(~100),我想绘制并保存为图像。我也找到了解决方案,但我真的不喜欢它。问题可以简化为有关 JPanel 的绘制状态的通知。
在保存所有图像的部分我有这个解决方案:
PlotSpectrum spectrumWindow = getTheWindow(); //pseudo code...
// some stuff
ti = storage.getImage(channel, slice, frame, position);
spectrumWindow.plotData(false, andor.captureSpectrum(ti.pix), wave,
centerWave, fineGrating, exposureTime,
slitWidth, substractBackground);
spectrumWindow.repaint(); // probably not necessary
sleep(100); // this annoys me...
spectrumWindow.savePlot(path, true, config, null);
spectrumWindow 是一个 JPanel,它也显示在另一个 window 中,并且一切正常。 但是我真的不喜欢那里的睡眠(100)......没有它我要求重新粉刷但是直到我尝试保存 "snapshot" 的(这就是 savePlot 正在做的)才完成...)。我知道,其他线程和这些该死的同步问题...... 随着睡眠,我只是让它不必要地变慢,如果我等待的时间不够长,图像就不会完全绘制(例如,下半部分丢失)
有什么方法可以在重绘完成后立即得到通知吗?我可能对 Listener 也很好,更好的方法是使用监视器或类似的解决方案,或者现在正在重绘的方法(据我所知不存在?) 主 GUI(包括 JPanel spectrumWindow)和之前粘贴的代码在不同的线程中 运行。
我的代码中可能也很重要的部分如下。如果某些括号不匹配或某些变量未声明,请原谅,我删除了很多代码。
谢谢 schetefan24
class PlotSpectrum extends ApplicationFrame // that extends JFrame
{
public void plotData(boolean backgroundGiven, int[] spect, double[] wave_,
double centerWave, boolean fineGrating_, double exposureTime,
double slitWidth, boolean substractBackground)
{
//process data and store internally
replot();
}
private void replot()
{
XYSeries series = new XYSeries("Spectrum");
//add data to series
XYSeriesCollection collection = new XYSeriesCollection(series);
//setting up some labels and such stuff...
JFreeChart chart = ChartFactory.createXYLineChart(
title,
"Wavelength [nm]",
yLabel,
collection,
PlotOrientation.VERTICAL,
false,
false,
false
);
dataPanel.add(new ChartPanel(chart)); // this is contained in a Frame
}
public void savePlot(String path, boolean overWriteAll, HashMap<String,String> config, int[][] addData)
{
File output = new File(path);
//some more stuff, ask overwrite etc
if(image)
{
BufferedImage im = createImage();
String extension = path.substring(path.lastIndexOf(".")+1, path.length());
ImageIO.write(im, extension, output);
} else {
//that is an textexport, works fine
}
}
public BufferedImage createImage()
{
JPanel panel = (JPanel) flipChart.getSelectedComponent();
int w = panel.getWidth();
int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
return bi;
}
}
that I want to plot and save as images.
- 将数据添加到不可见面板。
- 创建一个
BufferedImage
的面板 - 使用上面的图像创建一个
ImageIcon
- 使用
setIcon(...)
方法 更新 - 上述步骤应在图标更改时生成
PropertyChange
事件。您可以使用ProperChangeListener
来监听这个事件。收到事件后,您可以重复步骤 1 - 4。
JLabel
(已添加到框架中)
查看 Screen Image。它将帮助您创建不可见组件的图像。
请注意,您并不是真的需要步骤 4-5。我只是添加了它们,这样您就可以在处理它们时看到这些图。如果您不想要视觉效果,那么您可能只是在 JLabel 上显示文本,指示当前正在转换哪个图。