J'utilise la classe SwingWorker
pour exécuter un processus dans un autre thread. Qu'est-ce que je veux, une fois ce thread a terminé le traitement, il devrait retourner un String
et aussi il devrait activer un JMenuItem
. J'utilise la méthode done()
dans la classe SwingWorker
pour activer le JMenuItem
mais je reçois un NullPinterException
. La méthode doInBackground()
renvoie une chaîne à laquelle je souhaite accéder dans la classe GUI principale - GUIMain.java
, présente dans le même package. Comment devrais-je faire ça? J'ai vu de nombreux exemples qui mettent en œuvre done()
ou onPostExecute()
méthodes, mais je pense que je me trompe quelque part. Voici le code que je mis en œuvre:Comment renvoyer la valeur de la classe SwingWorker et l'utiliser dans une autre classe et activer MenuItem lorsque le processus est terminé?
public class GUIMain extends JFrame implements ActionListener, FocusListener, ItemListener, MouseListener, MouseMotionListener {
private JMenuBar menuBar; // Defined a menuBar item
private JMenu recalibrationMenu; // Define the recalibration menu item
private JMenuItem CGMenuItem;
private JMenuItem TGMenuItem;
private JMenu viewResultsMenu; // Define the View Results menu item
public JMenuItem cgResults;
public JMenuItem tgResults;
private JPanel TGImage;
private JPanel TGPanel;
private JPanel CGImage;
private JPanel CGPanel;
private JPanel CGRecalibrationParameters;
private JDialog resultsParameters;
private JLabel massPeakLabel = new JLabel("Select mass peak (m/z)");
private JTextField massPeakField = new JTextField(5);
private JLabel massWindowLabel = new JLabel("Mass window (Da)");
private JTextField massWindowField = new JTextField(5);
private float mzPeakValue;
private float massWindowValue;
private JButton massPeakSelectionButton = new JButton("OK");
private JButton CloseDialogButton = new JButton("Cancel");
private String CGRecalibratedFilesPath;
private String TGRecalibratedFilesPath;
/** Constructor to setup the GUI */
public GUIMain(String title) {
super(title);
setLayout(new BorderLayout());
menuBar = new JMenuBar();
menuBar.setBorder(new BevelBorder(BevelBorder.RAISED));
// build the Recalibration menu
recalibrationMenu = new JMenu("Recalibration");
CGMenuItem = new JMenuItem("Crystal Growth");
CGMenuItem.setEnabled(false); //initially disabled when app is launched
CGMenuItem.addActionListener(this);
TGMenuItem = new JMenuItem("Topological Greedy");
TGMenuItem.setEnabled(false); //initially disabled when app is launched
TGMenuItem.addActionListener(this);
recalibrationMenu.add(CGMenuItem);
recalibrationMenu.add(TGMenuItem);
// build the View Results menu
viewResultsMenu = new JMenu("View Results");
cgResults = new JMenuItem("CG Recalibration");
cgResults.setEnabled(false); //initially disabled when app is launched
cgResults.addActionListener(this);
tgResults = new JMenuItem("TG Recalibration");
tgResults.setEnabled(false); //initially disabled when app is launched
tgResults.addActionListener(this);
viewResultsMenu.add(cgResults);
viewResultsMenu.add(tgResults);
// add menus to menubar
menuBar.add(fileMenu);
menuBar.add(recalibrationMenu);
menuBar.add(viewResultsMenu);
// put the menubar on the frame
setJMenuBar(menuBar);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Exit program if close-window button clicked
setPreferredSize(new Dimension(1300, 800)); // Set the preferred window size
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public GUIMain()
{
}
}
public void actionPerformed(ActionEvent e) {
//Handle CG menu item action
**if ((e.getSource() == CGMenuItem)) {
RecalibrationWorker rw = new RecalibrationWorker(file,"CG");
rw.processCompleted();
rw.setVisible(true);
cgResults.setEnabled(true);
}**
if ((e.getSource() == cgResults)) {
viewRecalibrationResults("CG Recalibration - View Results", "CG");
}
if ((e.getSource() == tgResults)) {
viewRecalibrationResults("TG Recalibration - View Results", "TG");
}
}
private void viewRecalibrationResults(String dialogTitle, final String recalibrationType) {
resultsParameters = new JDialog();
resultsParameters.setLayout(new GridBagLayout());
resultsParameters.setTitle(dialogTitle);
GridBagConstraints gc = new GridBagConstraints();
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.WEST;
gc.ipady = 20;
// gc.anchor = GridBagConstraints.WEST;
resultsParameters.add(massPeakLabel, gc);
commonMassThresholdLabel.setLabelFor(massPeakField);
gc.gridx = 1;
gc.gridy = 0;
gc.ipady = 0;
gc.anchor = GridBagConstraints.CENTER;
resultsParameters.add(massPeakField,gc);
massPeakField.setText("");
massPeakField.addActionListener(this);
massPeakField.addFocusListener(this);
gc.gridx = 0;
gc.gridy = 1;
gc.ipady = 20;
gc.anchor = GridBagConstraints.WEST;
resultsParameters.add(massWindowLabel, gc);
massWindowLabel.setLabelFor(massWindowField);
gc.gridx = 1;
gc.gridy = 1;
gc.ipady = 0;
gc.anchor = GridBagConstraints.CENTER;
resultsParameters.add(massWindowField,gc);
massWindowField.setText("");
massWindowField.addActionListener(this);
massWindowField.addFocusListener(this);
gc.gridx = 0;
gc.gridy = 2;
gc.anchor = GridBagConstraints.CENTER;
resultsParameters.add(massPeakSelectionButton, gc);
massPeakSelectionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ("CG".equals(recalibrationType))
recalibrationResults("CG");
else if ("TG".equals(recalibrationType))
recalibrationResults("TG");
}
});
massPeakSelectionButton.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
if ("CG".equals(recalibrationType))
recalibrationResults("CG");
else if ("TG".equals(recalibrationType))
recalibrationResults("TG");
}
}
@Override
public void keyReleased(KeyEvent e) {
}
});
gc.gridx = 1;
gc.gridy = 2;
gc.anchor = GridBagConstraints.EAST;
resultsParameters.add(CloseDialogButton,gc);
CloseDialogButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resultsParameters.dispose();
}
});
resultsParameters.setVisible(true);
resultsParameters.setLocationRelativeTo(this);
resultsParameters.setSize(270, 150);
resultsParameters.setResizable(false);
}
}
public class RecalibrationWorker extends JDialog {
private boolean isStarted = false;
private JLabel counterLabel = new JLabel("Recalibration not yet started");
private Worker worker = new Worker();
private JPanel recalibrationParameters;
private ButtonGroup radioButtonGroup = new ButtonGroup();
private JRadioButton rawSpectra = new JRadioButton("Use raw spectra");
private JRadioButton preprocessedSpectra = new JRadioButton("Use preprocessed spectra");
private static float commonMassThresholdValue;
private static float recalibrationThresholdValue;
private static double mergeSpectraThresholdValue;
private JLabel commonMassThresholdLabel = new JLabel("<html>Common Mass Window<br>(value between 0.01-0.9 Da)</html>");
private JTextField commonMassThresholdField = new JTextField(String.valueOf(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
commonMassThresholdValue = Float.parseFloat(commonMassThresholdField.getText());
recalibrationThresholdField.requestFocusInWindow();
}
}));
private JLabel recalibrationThresholdLabel = new JLabel("<html>Mass threshold to recalibrate two spectra<br>(value between 0.01-0.9 Da)</html>");
private JTextField recalibrationThresholdField = new JTextField(String.valueOf(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
recalibrationThresholdValue = Float.parseFloat(recalibrationThresholdField.getText());
mergeSpectraThresholdField.requestFocusInWindow();
}
}));
private JLabel mergeSpectraThresholdLabel = new JLabel("<html>Mass threshold to merge spectra<br>(value between 0.01-0.9 Da)</html>");
private JTextField mergeSpectraThresholdField= new JTextField(String.valueOf(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mergeSpectraThresholdValue = Float.parseFloat(mergeSpectraThresholdField.getText());
startButton.requestFocusInWindow();
}
}));
private JTextArea recalibrationStatus = new JTextArea(7,32);
private JScrollPane textAreaScrolling = new JScrollPane(recalibrationStatus);
private JButton startButton = new JButton(new AbstractAction("Recalibrate") {
@Override
public void actionPerformed(ActionEvent arg0) {
if(!isStarted) {
Worker w = new Worker();
w.addPropertyChangeListener(new RecalibrationWorkerPropertyHandler(RecalibrationWorker.this));
w.execute();
isStarted = false;
}
}
});
private JButton stopButton = new JButton(new AbstractAction("Stop") {
@Override
public void actionPerformed(ActionEvent arg0) {
worker.cancel(true);
}
});
public File file;
public String type;
public String resultFilePath;
public RecalibrationWorker(File dataFile, String recalibrationType) {
file = dataFile;
type = recalibrationType;
setLayout(new GridBagLayout());
if("CG".equals(recalibrationType))
setTitle("Crystal Growth Recalibration");
else if("TG".equals(recalibrationType))
setTitle("Topological Greedy Recalibration");
recalibrationParameters = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
radioButtonGroup.add(rawSpectra);
radioButtonGroup.add(preprocessedSpectra);
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.WEST;
recalibrationParameters.add(preprocessedSpectra,gc);
gc.gridx = 1;
gc.gridy = 0;
recalibrationParameters.add(rawSpectra,gc);
gc.gridx = 0;
gc.gridy = 1;
gc.ipady = 20;
gc.anchor = GridBagConstraints.WEST;
recalibrationParameters.add(commonMassThresholdLabel, gc);
commonMassThresholdLabel.setLabelFor(commonMassThresholdField);
commonMassThresholdField.setColumns(3);
commonMassThresholdField.setText("");
gc.gridx = 1;
gc.gridy = 1;
gc.ipady = 0;
gc.anchor = GridBagConstraints.CENTER;
recalibrationParameters.add(commonMassThresholdField, gc);
commonMassThresholdField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
commonMassThresholdValue = Float.parseFloat(commonMassThresholdField.getText());
recalibrationThresholdField.requestFocusInWindow();
}
});
gc.gridx = 0;
gc.gridy = 2;
gc.ipady = 20;
gc.anchor = GridBagConstraints.WEST;
recalibrationParameters.add(recalibrationThresholdLabel, gc);
recalibrationThresholdLabel.setLabelFor(recalibrationThresholdField);
recalibrationThresholdField.setColumns(3);
recalibrationThresholdField.setText("");
gc.gridx = 1;
gc.gridy = 2;
gc.ipady = 0;
gc.anchor = GridBagConstraints.CENTER;
recalibrationParameters.add(recalibrationThresholdField, gc);
recalibrationThresholdField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
recalibrationThresholdValue = Float.parseFloat(recalibrationThresholdField.getText());
mergeSpectraThresholdField.requestFocusInWindow();
}
});
gc.gridx = 0;
gc.gridy = 3;
gc.ipady = 20;
gc.anchor = GridBagConstraints.WEST;
recalibrationParameters.add(mergeSpectraThresholdLabel, gc);
mergeSpectraThresholdLabel.setLabelFor(mergeSpectraThresholdField);
mergeSpectraThresholdField.setText("");
gc.gridx = 1;
gc.gridy = 3;
gc.ipady = 0;
gc.anchor = GridBagConstraints.CENTER;
recalibrationParameters.add(mergeSpectraThresholdField, gc);
mergeSpectraThresholdField.setColumns(3);
mergeSpectraThresholdField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
mergeSpectraThresholdValue = Double.parseDouble(mergeSpectraThresholdField.getText());
startButton.requestFocusInWindow();
}
});
recalibrationParameters.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Parameters"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
gc.gridx = 0;
gc.gridy = 4;
gc.anchor = GridBagConstraints.EAST;
recalibrationParameters.add(startButton, gc);
gc.gridx = 1;
gc.gridy = 4;
gc.anchor = GridBagConstraints.WEST;
recalibrationParameters.add(stopButton, gc);
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.CENTER;
add(recalibrationParameters, gc);
textAreaScrolling.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Recalibration status"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
gc.gridx = 0;
gc.gridy = 1;
gc.anchor = GridBagConstraints.CENTER;
add(textAreaScrolling, gc);
recalibrationStatus.setWrapStyleWord(true);
recalibrationStatus.setLineWrap(true);
recalibrationStatus.setEditable(false);
setVisible(true);
setLocationRelativeTo(this);
setSize(415, 425);
setResizable(false);
pack();
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
// constructor
public RecalibrationWorker()
{
}
public float commonMassThreshold() {
return commonMassThresholdValue;
}
public float recalibrationThreshold() {
return recalibrationThresholdValue;
}
public double mergeSpectraThreshold() {
return mergeSpectraThresholdValue;
}
protected String processCompleted() {
return resultFilePath;
}
protected void processFailed() {
System.out.println("Recalibration failed");
}
class Worker extends SwingWorker<String,String> {
// String resultfilePath;
@Override
public String doInBackground() throws Exception {
InputData inputDataObject1 = new InputData();
if(type == "CG")
{
resultFilePath = inputDataObject1.startRecalibration(file, type);
publish("Recalibration Successful!\nFiles can be found at: " + resultFilePath);
}
else if (type == "TG")
{
resultFilePath = inputDataObject1.startRecalibration(file, type);
publish("Recalibration Successful!\nFiles can be found at: " + resultFilePath);
}
return resultFilePath;
}
public void done() {
try {
get();
} catch (Exception e) {
}
}
@Override
protected void process(java.util.List<String> chunks) {
String value = chunks.get(chunks.size() - 1);
recalibrationStatus.append("\n"+value);
// recalibrationStatus.append(chunks.toString());
}
}
import javax.swing.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
/**
* Created by localadm on 27/09/15.
*/
public class RecalibrationWorkerPropertyHandler implements PropertyChangeListener {
private RecalibrationWorker rwObject;
public RecalibrationWorkerPropertyHandler(RecalibrationWorker rwObject) {
this.rwObject = rwObject;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
// System.out.println(evt.getPropertyName());
if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
// int value = (int) evt.getNewValue();
// rwObject.showProgress(value);
} else if ("state".equalsIgnoreCase(evt.getPropertyName())) {
SwingWorker worker = (SwingWorker) evt.getSource();
if (worker.isDone()) {
try {
worker.get();
System.out.println("I am here");
rwObject.processCompleted();
} catch (InterruptedException exp) {
rwObject.processFailed();
} catch (ExecutionException e) {
rwObject.processFailed();
}
}
}
}
}
Il y a quelques façons dont vous pourriez être en mesure de, vous pouvez utiliser un [modèle observateur] (http: // www.oodesign.com/observer-pattern.html) et la méthode 'done' pour renvoyer les résultats lorsque le travail est terminé ou vous pouvez utiliser le support' PropertyChangeListener' du worker et surveiller la propriété 'state' et quand' l'état ' 'change en' DONE', vous effectuez une autre action. La clé ici est que vous voulez notifier l'instance de l'objet qui est réellement sur l'écran, pas créer une nouvelle instance complètement indépendante – MadProgrammer
'if (type ==" CG ")' n'est pas comment fonctionne la comparaison 'String' en Java, vous devriez utiliser 'if (" CG ".equals (type))' à la place – MadProgrammer
[Pour un exemple 'PropertyChangeListener'] (http://stackoverflow.com/questions/23125642/swingworker-in-another-swingworkers -done-method/23126410 # 23126410) – MadProgrammer