我正在使用SwingWorker
类执行后台任务。 GUI
的许多不同组件都会在后台线程完成后进行更新(它们在done()
方法中)。 doInBackground()
方法发布HeatMap
类对象,而process()
方法将其添加到JPanel
组件。我已将MouseListener
和MouseMotionListener
添加到此Heatmap
类对象。 mouseMoved()
方法位于主GUI类中。移动鼠标时,鼠标在HeatMap
上的坐标位置应在JLabel
中显示。
当我运行代码时,HeatMap
对象在JPanel
中可见,但是我认为EDT
无法访问它。这是因为,通过快速检查,我发现在rawIntensityMap
的HeatMap
方法中null
process()
对象不是SwingWorker
,但是在null
方法中它仍然是mouseMoved()
,由于这个原因,我得到了NullPointerException
。HeatMap
类和GUIMain
类中的SwingWorker
对象已声明为:
private HeatMap rawIntensityMap = null;
我没有将
rawIntensityMap
对象发送到SwingWorker
类构造函数。我之前尝试过,但是没有用。这是
process()
类中的SwingWorker
方法: @Override
protected void process(List<HeatMap> chunks) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
imagePanel.add(rawIntensityMap, BorderLayout.CENTER);
coordinates.setBounds(31, 31, rawIntensityMap.getWidth() - 31, rawIntensityMap.getHeight() - 31);
}
});
}
这是
mouseMoved()
方法:@Override
public void mouseMoved(MouseEvent e) {
System.out.println("I am in the mouseevent" + coordinates.toString());
System.out.println("Width of raw Intensity map: " + rawIntensityMap.getWidth());
if (e.getPoint().x >= 31 && e.getPoint().y >= 31 && e.getPoint().x <= rawIntensityMap.getWidth() - 31 && e.getPoint().y <= rawIntensityMap.getHeight() - 31) {
rawIntensityMap.removeAll();
rawIntensityMap.add(coordinates);
coordinates.setText("(x,y) = " + "(" + (e.getPoint().x - 31) + "," + (e.getPoint().y - 31) + ")");
if (peakPickedImage.isSelected()) {
preprocessedIntensityMap.add(coordinates);
coordinates.setText("(x,y) = " + "(" + (e.getPoint().x - 31) + "," + (e.getPoint().y - 31) + ")");
coordinates.revalidate();
coordinates.repaint();
}
coordinates.revalidate();
coordinates.repaint();
}
}
这是我的
SwingWorker
类的基本结构:public class FileReadWorker extends SwingWorker<REXP, HeatMap> {
public FileReadWorker(GUIMain guiClassObject, File fileName, JTree rawSpectraTree, DefaultTreeModel model, DefaultMutableTreeNode root, String currentPath, JTextField minMz, JTextField maxMz, JFreeChart spectrumPlot, ChartPanel chartPanel, JPanel chartContent, float minMzValue, float maxMzValue, Float globalMinMz, Float globalMaxMz, JLabel statusLabel, JPanel imagePanel, JLabel coordinates, JTabbedPane tabbedSpectralFiles, JScrollPane spectralFilesScrollPane, JPanel rawFilesPanel, JRadioButton rawImage, JRadioButton peakPickedImage, JMenuItem loadPeakListMenuItem, JButton loadPeaklistsButton, JMenuItem propertiesMenuItem, JButton propertiesButton) {
this.guiClassObject = guiClassObject;
this.fileName = fileName;
this.rawSpectraTree = rawSpectraTree;
this.currentPath = currentPath;
this.minMz = minMz;
this.maxMz = maxMz;
this.spectrumPlot = spectrumPlot;
this.chartPanel = chartPanel;
this.chartContent = chartContent;
this.minMzValue = minMzValue;
this.maxMzValue = maxMzValue;
this.GlobalMinMz = globalMinMz;
this.GlobalMaxMz = globalMaxMz;
this.statusLabel = statusLabel;
this.imagePanel = imagePanel;
this.coordinates = coordinates;
this.tabbedSpectralFiles = tabbedSpectralFiles;
this.spectralFilesScrollPane = spectralFilesScrollPane;
this.rawFilesPanel = rawFilesPanel;
this.rawImage = rawImage;
this.peakPickedImage = peakPickedImage;
this.loadPeakListMenuItem = loadPeakListMenuItem;
this.loadPeaklistsButton = loadPeaklistsButton;
this.propertiesMenuItem = propertiesMenuItem;
this.propertiesButton = propertiesButton;
this.model = model;
this.root = root;
}
@Override
protected REXP doInBackground() throws Exception {
// does some background tasks
// Works on the generating the HeatMap
try {
rawIntensityMap = gim.generateIntensityMap(rawSpectrumObjects, currentPath, minMzValue, maxMzValue, Gradient.GRADIENT_Rainbow, "RAW");
publish(rawIntensityMap);
} catch (RserveException e) {
e.printStackTrace();
} catch (REXPMismatchException e) {
e.printStackTrace();
}
// returns a REXP object
return rawSpectrumObjects;
}
@Override
public void done() {
// Updates different components of the GUI
rawIntensityMap.addMouseListener(guiClassObject);
rawIntensityMap.addMouseMotionListener(guiClassObject);
}
}
}
有人可以在这里指出错误吗?
更多代码:
这是我的
GUIMain
类,其中声明了HeatMap rawIntensityMap
。另外,我已经将部分代码粘贴到实际使用该HeatMap
对象的地方(尚未粘贴所有方法)。 public class GUIMain extends JFrame implements ActionListener, ItemListener, MouseListener, MouseMotionListener, ChangeListener {
volatile HeatMap rawIntensityMap;
private JPanel imagePanel; // container for the HeatMap
/**
* Constructor to setup the GUI
*/
public GUIMain(String title) {
super(title);
setLayout(new BorderLayout());
//getSize();
setSize(getSize());
imagePanel = new JPanel(new BorderLayout());
g.gridx = 0;
g.gridy = 1;
g.gridwidth = 2;
g.weightx = 1.0; // fill the rest of the space
g.weighty = 1.0;
g.fill = GridBagConstraints.BOTH;
imagePanel.setBorder(BorderFactory.createEtchedBorder());
//imagePanel.addMouseListener(this);
imageDisplay.add(imagePanel, g);
// ImageDisplay.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
imageDisplay.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("View 2-D ion intensity map"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
}
public void actionPerformed(ActionEvent e) {
//Handle open *.img imaging file button and menu item action
if ((e.getSource() == OpenImagingFileButton) || (e.getSource() == loadRawSpectraMenuItem)) {
int returnVal = fcImg.showOpenDialog(GUIMain.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fcImg.getSelectedFile();
root = new DefaultMutableTreeNode(file);
rawSpectraTree = new JTree(root);
model = (DefaultTreeModel) rawSpectraTree.getModel();
//Passing this HeatMap to the SwingWorker class
FileReadWorker frw = new FileReadWorker(this, file, rawSpectraTree, rawIntensityMap, model, root, currentPath, minMz, maxMz, spectrumPlot, chartPanel, chartContent, minMzValue, maxMzValue, GlobalMinMz, GlobalMaxMz, statusLabel, imagePanel, coordinates, tabbedSpectralFiles, spectralFilesScrollPane, rawFilesPanel, rawImage, peakPickedImage, loadPeakListMenuItem, loadPeaklistsButton, propertiesMenuItem, propertiesButton);
frw.execute();
}
// Method when a different HeatMap color gradient is selected
@Override
public void itemStateChanged(ItemEvent e) {
colorNumber = (Integer) e.getItem();
if (e.getStateChange() == ItemEvent.SELECTED) {
rawIntensityMap.updateGradient(gradients[colorNumber]);
if (peakPickedImage.isEnabled()) {
preprocessedIntensityMap.updateGradient(gradients[colorNumber]);
}
}
}
// Mouse moved event
@Override
public void mouseMoved(MouseEvent e) {
if(rawIntensityMap == null)
System.out.println("TRUE**");
else
System.out.println("FALSE**");
System.out.println("I am in the mouseevent" + coordinates.toString());
if (e.getPoint().x >= 31 && e.getPoint().y >= 31 && e.getPoint().x <= rawIntensityMap.getWidth() - 31 && e.getPoint().y <= rawIntensityMap.getHeight() - 31) {
rawIntensityMap.removeAll();
rawIntensityMap.add(coordinates);
coordinates.setText("(x,y) = " + "(" + (e.getPoint().x - 31) + "," + (e.getPoint().y - 31) + ")");
if (peakPickedImage.isSelected()) {
preprocessedIntensityMap.add(coordinates);
coordinates.setText("(x,y) = " + "(" + (e.getPoint().x - 31) + "," + (e.getPoint().y - 31) + ")");
coordinates.revalidate();
coordinates.repaint();
}
coordinates.revalidate();
coordinates.repaint();
}
}
}
SwingWorker
类中的代码已在上面粘贴。 最佳答案
您有两个完全独立的字段,名为rawIntensityMap
。
您有GUIMain.rawIntensityMap
和FileReadWorker.rawIntensityMap
。您在FileReadWorker.rawIntensityMap
中分配了FileReadWorker::doInBackground
,但从未将GUIMain.rawIntensityMap
分配给任何值。
尝试在rawIntensityMap
中为GUIMain
创建设置器,并在guiClassObject.setRawIntensityMap(rawIntensityMap);
中调用FileReadWorker::done
。