我正在使用SwingWorker类执行后台任务。 GUI的许多不同组件都会在后台线程完成后进行更新(它们在done()方法中)。 doInBackground()方法发布HeatMap类对象,而process()方法将其添加到JPanel组件。我已将MouseListenerMouseMotionListener添加到此Heatmap类对象。 mouseMoved()方法位于主GUI类中。移动鼠标时,鼠标在HeatMap上的坐标位置应在JLabel中显示。

当我运行代码时,HeatMap对象在JPanel中可见,但是我认为EDT无法访问它。这是因为,通过快速检查,我发现在rawIntensityMapHeatMap方法中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.rawIntensityMapFileReadWorker.rawIntensityMap。您在FileReadWorker.rawIntensityMap中分配了FileReadWorker::doInBackground,但从未将GUIMain.rawIntensityMap分配给任何值。

尝试在rawIntensityMap中为GUIMain创建设置器,并在guiClassObject.setRawIntensityMap(rawIntensityMap);中调用FileReadWorker::done

07-26 09:27