我正在使用SwingWorker
类来执行后台任务。后台线程完成后GUI
的许多不同组件都是job(这些都在done()
方法中)。 doInBackground()
方法发布HeatMap
类对象,process()
方法将其添加到JPanel
组件。我已将MouseListener
和MouseMotionListener
添加到此Heatmap
类对象中。 {GUI}类中存在mouseMoved()
方法。移动鼠标时,应在HeatMap
中显示鼠标在JLabel
上的坐标位置。
当我运行代码时,HeatMap
对象在JPanel
中可见,但我认为EDT
无法访问它。这是因为,通过快速检查,我发现rawIntensityMap
的{{1}}方法中的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();
}
}
}
类的代码已经粘贴在上面。
答案 0 :(得分:2)
您有两个名为rawIntensityMap
的完全独立的字段。
您有GUIMain.rawIntensityMap
和FileReadWorker.rawIntensityMap
。您在FileReadWorker.rawIntensityMap
中分配了FileReadWorker::doInBackground
,但从未将GUIMain.rawIntensityMap
分配给任何值。
尝试在rawIntensityMap
中为GUIMain
创建一个setter,并在guiClassObject.setRawIntensityMap(rawIntensityMap);
中调用FileReadWorker::done
。