Problems in using SwingWorker class for reading a

2019-09-10 15:47发布

问题:

Note: This question may look like a repetition of several question posted on the forum, but I am really stuck on this problem from quite some time and I am not able to solve this issue using the solutions posted for similar questions. I have posted my code here and need help to proceed further
So, here is my issue: I am writing a Java GUI application which loads a file before performing any processing. There is a waiting time on an average of about 10-15 seconds during which the file is parsed. After this waiting time, what I get see on the GUI is,

  1. The parsed file in the form of individual leaves in the JTree in a Jpanel
  2. Some header information (example: data range) in two individual JTextField
  3. A heat map generated after parsing the data in a different JPanel on the GUI.

The program connects to R to parse the file and read the header information.

Now, I want to use swing worker to put the file reading process on a different thread so that it does not block the EDT. I am not sure how I can build my SwingWorker class so that the process is done in the background and the results for the 3 components are displayed when the process is complete. And, during this file reading process I want to display a JProgressBar.

Here is the code which does the whole process, starting from selection of the file selection menu item. This is in the main GUI method.

    JScrollPane spectralFilesScrollPane;
                if ((e.getSource() == OpenImagingFileButton) || (e.getSource() == loadRawSpectraMenuItem)) {
                    int returnVal = fcImg.showOpenDialog(GUIMain.this);
    // File chooser
                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        file = fcImg.getSelectedFile();


        //JTree and treenode creation
                        DefaultMutableTreeNode root = new DefaultMutableTreeNode(file);
                        rawSpectraTree = new JTree(root);
                        DefaultTreeModel model = (DefaultTreeModel) rawSpectraTree.getModel();

                        try {

// R connection
                            rc = new RConnection();
                            final String inputFileDirectory = file.getParent();
                            System.out.println("Current path: " + currentPath);

                           rc.assign("importImagingFile", currentPath.concat("/importImagingFile.R"));
                            rc.eval("source(importImagingFile)");

                            rc.assign("currentWorkingDirectory", currentPath);
                            rc.assign("inputFileDirectory", inputFileDirectory);

                            rawSpectrumObjects = rc.eval("importImagingFile(inputFileDirectory,currentWorkingDirectory)");

                            rc.assign("plotAverageSpectra", currentPath.concat("/plotAverageSpectra.R"));
                            rc.eval("source(plotAverageSpectra)");
                            rc.assign("rawSpectrumObjects", rawSpectrumObjects);

                            REXP averageSpectraObject = rc.eval("plotAverageSpectra(rawSpectrumObjects)");

                            rc.assign("AverageMassSpecObjectToSpectra", currentPath.concat("/AverageMassSpecObjectToSpectra.R"));
                            rc.eval("source(AverageMassSpecObjectToSpectra)");
                            rc.assign("averageSpectraObject", averageSpectraObject);

                            REXP averageSpectra = rc.eval("AverageMassSpecObjectToSpectra(averageSpectraObject)");

                            averageSpectraMatrix = averageSpectra.asDoubleMatrix();

                              String[] spectrumName = new String[rawSpectrumObjects.asList().size()];
                            for (int i = 0; i < rawSpectrumObjects.asList().size(); i++) {
                                DefaultMutableTreeNode node = new DefaultMutableTreeNode("Spectrum_" + (i + 1));
                                model.insertNodeInto(node, root, i);
                            }

                            // Expand all the nodes of the JTree
                            for(int i=0;i< model.getChildCount(root);++i){
                                rawSpectraTree.expandRow(i);
                            }

                            DefaultMutableTreeNode firstLeaf = ((DefaultMutableTreeNode)rawSpectraTree.getModel().getRoot()).getFirstLeaf();
                            rawSpectraTree.setSelectionPath(new TreePath(firstLeaf.getPath()));
                            updateSpectralTableandChartRAW(firstLeaf);

                            // List the min and the max m/z of in the respective data fields
                            rc.assign("dataMassRange", currentPath.concat("/dataMassRange.R"));
                            rc.eval("source(dataMassRange)");
                            rc.assign("rawSpectrumObjects", rawSpectrumObjects);

                            REXP massRange = rc.eval("dataMassRange(rawSpectrumObjects)");

                            double[] massRangeValues = massRange.asDoubles();
                            minMzValue = (float)massRangeValues[0];
                            maxMzValue = (float)massRangeValues[1];

                            GlobalMinMz = minMzValue;
                            GlobalMaxMz = maxMzValue;
        // Adds the range values to the jTextField
                            minMz.setText(Float.toString(minMzValue));

                            minMz.validate();
                            minMz.repaint();

                            maxMz.setText(Float.toString(maxMzValue));

                            maxMz.validate();
                            maxMz.repaint();

                            // Update status bar with the uploaded data details
                            statusLabel.setText("File name: " + file.getName() + "    |    " + "Total spectra: " + rawSpectrumObjects.asList().size() + "    |    " + "Mass range: " + GlobalMinMz + "-" + GlobalMaxMz);
        // Generates a heatmap
                            rawIntensityMap = gim.generateIntensityMap(rawSpectrumObjects, currentPath, minMzValue, maxMzValue, Gradient.GRADIENT_Rainbow, "RAW");
                            rawIntensityMap.addMouseListener(this);
                            rawIntensityMap.addMouseMotionListener(this);
                            imagePanel.add(rawIntensityMap, BorderLayout.CENTER);

                            coordinates = new JLabel();
                            coordinates.setBounds(31, 31, rawIntensityMap.getWidth() - 31, rawIntensityMap.getHeight() - 31);

                            panelRefresh(imagePanel);

                            tabbedSpectralFiles.setEnabledAt(1, false);

                            rawSpectraTree.addTreeSelectionListener(new TreeSelectionListener() {

                                @Override
                                public void valueChanged(TreeSelectionEvent e) {
                                    try {
                                        DefaultMutableTreeNode selectedNode =
                                                (DefaultMutableTreeNode) rawSpectraTree.getLastSelectedPathComponent();

                                        int rowCount = listTableModel.getRowCount();

                                        for (int l = 0; l < rowCount; l++) {
                                            listTableModel.removeRow(0);
                                        }

                                        updateSpectralTableandChartRAW(selectedNode);

                                    } catch (RserveException e2) {
                                        e2.printStackTrace();
                                    } catch (REXPMismatchException e1) {
                                        e1.printStackTrace();
                                    }
                                }
                            });

                            spectralFilesScrollPane = new JScrollPane();
                            spectralFilesScrollPane.setViewportView(rawSpectraTree);
                            spectralFilesScrollPane.setPreferredSize(rawFilesPanel.getSize());

                            rawFilesPanel.add(spectralFilesScrollPane);
                            tabbedSpectralFiles.validate();
                            tabbedSpectralFiles.repaint();

                            rawImage.setEnabled(true);
                            peakPickedImage.setEnabled(false);

                            loadPeakListMenuItem.setEnabled(true); //active now
                            loadPeaklistsButton.setEnabled(true); //active now

                            propertiesMenuItem.setEnabled(true); // active now
                            propertiesButton.setEnabled(true); //active now

                        } catch (RserveException e1) {
                            JOptionPane.showMessageDialog(this,
                                    "There was an error in the R connection. Please try again!", "Error",
                                    JOptionPane.ERROR_MESSAGE);
                        } catch (REXPMismatchException e1) {
                            JOptionPane.showMessageDialog(this,
                                    "Operation requested is not supported by the given R object type. Please try again!", "Error",
                                    JOptionPane.ERROR_MESSAGE);
                        }
                      //  hideProgress();
                    }
                }

I tried creating a SwingWorker class, but I am totally confused how I can get all the three outputs on the GUI, plus have a progress bar. It is not complete, but I don't know how to proceed further.

public class FileReadWorker extends SwingWorker<REXP, String>{

    private static void failIfInterrupted() throws InterruptedException {
        if (Thread.currentThread().isInterrupted()) {
            throw new InterruptedException("Interrupted while loading imaging file!");
        }
    }

    // The file that is being read
    private final File fileName;
    private JTree rawSpectraTree;
    private RConnection rc;
    private REXP rawSpectrumObjects;
    private double[][] averageSpectraMatrix;
    private Path currentRelativePath = Paths.get("");
    private final String currentPath = currentRelativePath.toAbsolutePath().toString();
    final JProgressBar progressBar = new JProgressBar();
//    public FileReadWorker(File fileName)
//    {
//        this.fileName = fileName;
//        System.out.println("I am here");
//    }


    public FileReadWorker(final JProgressBar progressBar, File fileName) {
        this.fileName = fileName;
        addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if ("progress".equals(evt.getPropertyName())) {
                    progressBar.setValue((Integer) evt.getNewValue());
                }
            }
        });

        progressBar.setVisible(true);
        progressBar.setStringPainted(true);
        progressBar.setValue(0);
        setProgress(0);
    }


    @Override
    protected REXP doInBackground() throws Exception {

        System.out.println("I am here... in background");

        DefaultMutableTreeNode root = new DefaultMutableTreeNode(fileName);
        rawSpectraTree = new JTree(root);
        DefaultTreeModel model = (DefaultTreeModel) rawSpectraTree.getModel();

        rc = new RConnection();
        final String inputFileDirectory = fileName.getParent();

        rc.assign("importImagingFile", currentPath.concat("/importImagingFile.R"));
        rc.eval("source(importImagingFile)");

        rc.assign("currentWorkingDirectory", currentPath);
        rc.assign("inputFileDirectory", inputFileDirectory);

        rawSpectrumObjects = rc.eval("importImagingFile(inputFileDirectory,currentWorkingDirectory)");

        rc.assign("plotAverageSpectra", currentPath.concat("/plotAverageSpectra.R"));
        rc.eval("source(plotAverageSpectra)");
        rc.assign("rawSpectrumObjects", rawSpectrumObjects);

        REXP averageSpectraObject = rc.eval("plotAverageSpectra(rawSpectrumObjects)");

        rc.assign("AverageMassSpecObjectToSpectra", currentPath.concat("/AverageMassSpecObjectToSpectra.R"));
        rc.eval("source(AverageMassSpecObjectToSpectra)");
        rc.assign("averageSpectraObject", averageSpectraObject);

        REXP averageSpectra = rc.eval("AverageMassSpecObjectToSpectra(averageSpectraObject)");

        averageSpectraMatrix = averageSpectra.asDoubleMatrix();

        for (int i = 0; i < rawSpectrumObjects.asList().size(); i++) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode("Spectrum_" + (i + 1));
            model.insertNodeInto(node, root, i);
        }

        // Expand all the nodes of the JTree
        for(int i=0;i< model.getChildCount(root);++i){
            rawSpectraTree.expandRow(i);
        }
        return averageSpectra;
    }

    @Override
    public void done() {
        setProgress(100);
        progressBar.setValue(100);
        progressBar.setStringPainted(false);
        progressBar.setVisible(false);
    }
}

Any help would be very much appreciated.