f@0: /* f@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool f@0: f@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) f@0: f@0: This program is free software: you can redistribute it and/or modify f@0: it under the terms of the GNU General Public License as published by f@0: the Free Software Foundation, either version 3 of the License, or f@0: (at your option) any later version. f@0: f@0: This program is distributed in the hope that it will be useful, f@0: but WITHOUT ANY WARRANTY; without even the implied warranty of f@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the f@0: GNU General Public License for more details. f@0: f@0: You should have received a copy of the GNU General Public License f@0: along with this program. If not, see . f@0: */ f@0: f@0: package uk.ac.qmul.eecs.ccmi.gui; f@0: f@0: import java.awt.Color; f@0: import java.awt.Component; f@0: import java.awt.Frame; f@0: import java.awt.GridLayout; f@0: import java.awt.event.ActionEvent; f@0: import java.awt.event.ActionListener; f@0: import java.awt.event.InputEvent; f@0: import java.awt.event.KeyEvent; f@0: import java.awt.event.WindowAdapter; f@0: import java.awt.event.WindowEvent; f@0: import java.text.MessageFormat; f@0: import java.util.LinkedHashSet; f@0: import java.util.List; f@0: import java.util.ResourceBundle; f@0: import java.util.Set; f@0: f@0: import javax.swing.AbstractAction; f@0: import javax.swing.JButton; f@0: import javax.swing.JCheckBox; f@0: import javax.swing.JComponent; f@0: import javax.swing.JDialog; f@0: import javax.swing.JFormattedTextField; f@0: import javax.swing.JLabel; f@0: import javax.swing.JOptionPane; f@0: import javax.swing.JPanel; f@0: import javax.swing.JProgressBar; f@0: import javax.swing.JScrollPane; f@0: import javax.swing.JSpinner; f@0: import javax.swing.JTextArea; f@0: import javax.swing.JTextField; f@0: import javax.swing.KeyStroke; f@0: import javax.swing.SwingWorker; f@0: import javax.swing.event.ChangeEvent; f@0: import javax.swing.event.ChangeListener; f@0: import javax.swing.text.JTextComponent; f@0: f@0: import uk.ac.qmul.eecs.ccmi.sound.SoundEvent; f@0: import uk.ac.qmul.eecs.ccmi.sound.SoundFactory; f@0: import uk.ac.qmul.eecs.ccmi.speech.Narrator; f@0: import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory; f@0: import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities; f@0: f@0: /** f@0: * f@0: * An option panel made out of an {@code Object} being displayed and to buttons: one for accepting and another one for f@0: * cancelling the option. f@0: * Furthermore, this class provides one-line calls to display accessible dialog boxes. Input by the user as well f@0: * as focused components are spoken out through text to speech synthesis performed by a {@link Narrator} instance. f@0: */ f@0: public class SpeechOptionPane { f@0: f@0: /** f@0: * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog f@0: * that is displayed after a call to {@code showDialog} f@0: */ f@0: public SpeechOptionPane(){ f@0: this(""); f@0: } f@0: f@0: /** f@0: * Construct a new {@code SpeechOptionPane} with no title. The title is displayed at the top of the dialog f@0: * that is displayed after a call to {@code showDialog} f@0: * f@0: * @param title the String to be displayed f@0: */ f@0: public SpeechOptionPane(String title){ f@0: this.title = title; f@0: okButton = new JButton("OK"); f@0: cancelButton = new JButton("Cancel"); f@0: } f@0: f@0: /** f@0: * Pops the a dialog holding this SpeechOptionPane f@0: * f@0: * @param parent the parent component of the dialog f@0: * @param message the {@code Object} to display f@0: * @return an integer indicating the option selected by the user f@0: */ f@0: @SuppressWarnings("serial") f@0: public int showDialog(Component parent,final Object message){ f@0: optPane = new JOptionPane(); f@0: optPane.setMessage(message); f@0: /* Enter will entail a unique action, regardless the component that's focused */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "closeDialog"); f@0: optPane.getActionMap().put("closeDialog", new AbstractAction(){ f@0: @Override f@0: public void actionPerformed(ActionEvent evt) { f@0: okButton.doClick(); f@0: } f@0: }); f@0: optPane.setMessageType(JOptionPane.PLAIN_MESSAGE); f@0: Object[] options = { f@0: okButton, f@0: cancelButton f@0: }; f@0: optPane.setOptions(options); f@0: /* ctrl key will hush the TTS */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up"); f@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction()); f@0: final JDialog dialog = optPane.createDialog(parent, title); f@0: dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); f@0: SpeechUtilities.changeTabListener(optPane,dialog); f@0: /* when either button is pressed, dialog is disposed and the button itself becomes the optPane.value */ f@0: ActionListener buttonListener = new ActionListener(){ f@0: @Override f@0: public void actionPerformed(ActionEvent evt) { f@0: onClose(dialog,(JButton)evt.getSource()); f@0: } f@0: }; f@0: okButton.addActionListener(buttonListener); f@0: cancelButton.addActionListener(buttonListener); f@0: f@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING); f@0: dialog.setVisible(true); f@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING); f@0: if(okButton.equals(optPane.getValue())){ f@0: return OK_OPTION; f@0: }else{ f@0: return CANCEL_OPTION; f@0: } f@0: } f@0: f@0: /** f@0: * Sets the string appearing at the top of the dialog where this option pane is displayed when {@code showDialog} f@0: * is called. f@0: * @param title the title of this option pane f@0: */ f@0: public void setDialogTitle(String title){ f@0: this.title = title; f@0: } f@0: f@0: /** f@0: * Returns the {@code JButton} that the user has to press (when the option pane is displayed after f@0: * {@code showDialog} is called) in order to accept the option. f@0: * f@0: * @return a reference to the internal {@code JButton} f@0: */ f@0: public JButton getOkButton(){ f@0: return okButton; f@0: } f@0: f@0: /** f@0: * Returns the {@code JButton} that the user has to press (when the option pane is displayed after f@0: * {@code showDialog} is called) in order to reject the option. f@0: * f@0: * @return a reference to the internal {@code JButton} f@0: */ f@0: public JButton getCancelButton(){ f@0: return cancelButton; f@0: } f@0: f@0: /** f@0: * This method is called just after the user presses either button of the dialog displayed f@0: * after {@code showDialog} is called. f@0: * It assign a value to the return value and it frees the dialog resources. f@0: * It can be overwritten by subclasses but care should be taken of calling this class method via f@0: * {@code super} in order to properly close the dialog. f@0: * f@0: * @param dialog the dialog displayed after {@code showDialog} is called. f@0: * @param source the button that triggered the closing of {@code dialog} f@0: */ f@0: protected void onClose(JDialog dialog, JButton source){ f@0: optPane.setValue(source); f@0: dialog.dispose(); f@0: } f@0: f@0: private String title; f@0: private JOptionPane optPane; f@0: private JButton okButton; f@0: private JButton cancelButton; f@0: f@0: f@0: /* -------- STATIC METHODS ----------- */ f@0: f@0: /** f@0: * Shows a dialog with a text area requesting input for the user. f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message a displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param text the initial text the text area contains when the dialog is displayed f@0: * f@0: * @return the new text entered by the user f@0: */ f@0: public static String showTextAreaDialog(Component parentComponent, String message, String text){ f@0: JTextArea textArea = new JTextArea(NOTES_TEXT_AREA_ROW_SIZE,NOTES_TEXT_AREA_COL_SIZE); f@0: textArea.setText(text); f@0: NarratorFactory.getInstance().speak(message); f@0: return textComponentDialog(parentComponent, message, textArea); f@0: } f@0: f@0: /** f@0: * Shows a dialog with a text field requesting input from the user f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param initialSelectionValue the initial text the text field contains when the dialog is displayed f@0: * f@0: * @return the text entered by the user f@0: */ f@0: public static String showInputDialog(Component parentComponent, String message, String initialSelectionValue){ f@0: final JTextField textField = new JTextField(initialSelectionValue); f@0: textField.selectAll(); f@0: NarratorFactory.getInstance().speak(message); f@0: return textComponentDialog(parentComponent, message, textField); f@0: } f@0: f@0: private static String textComponentDialog(Component parentComponent, String message, final JTextComponent textComponent){ f@0: Object componentToDisplay = textComponent; f@0: if(textComponent instanceof JTextArea) f@0: componentToDisplay = new JScrollPane(textComponent); f@0: f@0: Object[] displayObjects = { new JLabel(message), componentToDisplay }; f@0: final JOptionPane optPane = new JOptionPane(); f@0: optPane.setMessage(displayObjects); f@0: optPane.setMessageType(QUESTION_MESSAGE); f@0: optPane.setOptionType(OK_CANCEL_OPTION); f@0: /* ctrl key will hush the TTS */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up"); f@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction()); f@0: f@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input")); f@0: if(textComponent instanceof JTextArea) f@0: dialog.setResizable(true); f@0: dialog.addWindowFocusListener(new WindowAdapter(){ f@0: @Override f@0: public void windowGainedFocus(WindowEvent e) { f@0: textComponent.requestFocusInWindow(); f@0: } f@0: }); f@0: f@0: SpeechUtilities.changeTabListener(optPane,dialog); f@0: textComponent.addKeyListener(SpeechUtilities.getSpeechKeyListener(true)); f@0: textComponent.setEditable(true); f@0: // start the editing sound f@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING); f@0: dialog.setVisible(true); f@0: dialog.dispose(); f@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING); f@0: f@0: if(optPane.getValue() == null)//window closed f@0: return null; f@0: else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel f@0: return null; f@0: else{ // pressed on OK f@0: return textComponent.getText().trim(); f@0: } f@0: } f@0: f@0: /** f@0: * Shows a dialog with a {@code JComboBox} requesting selection from the user f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param options options for the {@code JComboBox} f@0: * @param initialValue the options value selected when the dialog is shown f@0: * @return the option selected by the user f@0: */ f@0: public static Object showSelectionDialog(Component parentComponent, String message, Object[] options, Object initialValue){ f@0: final LoopComboBox comboBox = new LoopComboBox(options); f@0: comboBox.setSelectedItem(initialValue); f@0: Object[] displayObjects = { new JLabel(message), comboBox }; f@0: JOptionPane optPane = new JOptionPane(); f@0: optPane.setMessage(displayObjects); f@0: optPane.setMessageType(QUESTION_MESSAGE); f@0: optPane.setOptionType(OK_CANCEL_OPTION); f@0: /* ctrl key will hush the TTS */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up"); f@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction()); f@0: f@0: NarratorFactory.getInstance().speak(message+", "+SpeechUtilities.getComponentSpeech(comboBox)); f@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.select")); f@0: dialog.addWindowFocusListener(new WindowAdapter(){ f@0: @Override f@0: public void windowGainedFocus(WindowEvent e) { f@0: comboBox.requestFocusInWindow(); f@0: } f@0: }); f@0: f@0: comboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener()); f@0: f@0: SpeechUtilities.changeTabListener(optPane,dialog); f@0: // start the editing sound f@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING); f@0: dialog.setVisible(true); f@0: dialog.dispose(); f@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING); f@0: if(optPane.getValue() == null)//window closed f@0: return null; f@0: else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel )//pressed on cancel f@0: return null; f@0: else{ // pressed on OK f@0: return comboBox.getSelectedItem(); f@0: } f@0: } f@0: f@0: /** f@0: * Shows the dialog with a {@code JSpinner} requesting the selection of the speech rate f@0: * of the main voice of the {@code Narrator} f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param value the initial value f@0: * @param min the minimum value of the spinner f@0: * @param max the maximum value of the spinner f@0: * @return the selected integer value or {@code null} if the user cancels the dialog f@0: */ f@0: public static Integer showNarratorRateDialog(Component parentComponent, String message, int value, int min, int max){ f@0: NarratorFactory.getInstance().speak(message); f@0: final JSpinner spinner = new JSpinner(new LoopSpinnerNumberModel(value,min,max)); f@0: JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField(); f@0: tf.setEditable(false); f@0: tf.setFocusable(false); f@0: tf.setBackground(Color.white); f@0: f@0: Object[] displayObjects = { new JLabel(message), spinner}; f@0: final JOptionPane optPane = new JOptionPane(); f@0: optPane.setMessage(displayObjects); f@0: optPane.setMessageType(QUESTION_MESSAGE); f@0: optPane.setOptionType(OK_CANCEL_OPTION); f@0: /* ctrl key will hush the TTS */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up"); f@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction()); f@0: f@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.input")); f@0: SpeechUtilities.changeTabListener(optPane,dialog); f@0: f@0: dialog.addWindowFocusListener(new WindowAdapter(){ f@0: @Override f@0: public void windowGainedFocus(WindowEvent e) { f@0: spinner.requestFocusInWindow(); f@0: } f@0: }); f@0: spinner.addChangeListener(new ChangeListener(){ f@0: @Override f@0: public void stateChanged(ChangeEvent evt) { f@0: JSpinner s = (JSpinner)(evt.getSource()); f@0: NarratorFactory.getInstance().setRate((Integer)s.getValue()); f@0: NarratorFactory.getInstance().speak(s.getValue().toString()); f@0: } f@0: }); f@0: // start the editing sound f@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING); f@0: dialog.setVisible(true); f@0: dialog.dispose(); f@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING); f@0: f@0: /* set the speech rate back to the value passed as argument */ f@0: NarratorFactory.getInstance().setRate(value); f@0: if(optPane.getValue() == null)//window closed f@0: return null; f@0: else if(((Integer)optPane.getValue()).intValue() == CANCEL_OPTION || ((Integer)optPane.getValue()).intValue() == CLOSED_OPTION)//pressed on cancel f@0: return null; f@0: else{ // pressed on OK f@0: return (Integer)spinner.getValue(); f@0: } f@0: } f@0: f@0: /** f@0: * Brings up a dialog with selected options requesting user to confirmation. f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message a message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param optionType an integer designating the options available on the dialog f@0: * @return an integer indicating the option selected by the user f@0: */ f@0: public static int showConfirmDialog(Component parentComponent, String message, int optionType){ f@0: NarratorFactory.getInstance().speak(message); f@0: JOptionPane optPane = new JOptionPane(); f@0: optPane.setMessage(message); f@0: optPane.setMessageType(QUESTION_MESSAGE); f@0: optPane.setOptionType(optionType); f@0: /* ctrl key will hush the TTS */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up"); f@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction()); f@0: f@0: JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm")); f@0: SpeechUtilities.changeTabListener(optPane,dialog); f@0: f@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING); f@0: dialog.setVisible(true); f@0: dialog.dispose(); f@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING); f@0: f@0: if(optPane.getValue() == null)//window closed f@0: return CANCEL_OPTION; f@0: else f@0: return ((Integer)optPane.getValue()).intValue(); f@0: } f@0: f@0: /** f@0: * Displays a message to the user. f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message the message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param messageType the type of message to be displayed f@0: */ f@0: public static void showMessageDialog(Component parentComponent, String message, int messageType){ f@0: NarratorFactory.getInstance().speak(MessageFormat.format(resources.getString("dialog.speech_option_pane.message"), message)); f@0: JOptionPane optPane = new JOptionPane(); f@0: optPane.setMessage(message); f@0: optPane.setMessageType(messageType); f@0: /* ctrl key will hush the TTS */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up"); f@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction()); f@0: f@0: JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.confirm")); f@0: SpeechUtilities.changeTabListener(optPane,dialog); f@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING); f@0: dialog.setVisible(true); f@0: dialog.dispose(); f@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING); f@0: } f@0: f@0: /** f@0: * Displays an error message to the user. f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message the message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: */ f@0: public static void showMessageDialog(Component parentComponent, String message){ f@0: showMessageDialog(parentComponent,message,ERROR_MESSAGE); f@0: } f@0: f@0: /** f@0: * Execute a ProgressDialogWorker task and f@0: * shows an indeterminate progress bar dialog if the task is not completed after f@0: * {@code millisToDecideToPopup}. The user can use the dialog cancel button f@0: * to cancel the task. f@0: * f@0: * @param the result type returned by the worker f@0: * @param the intermediate result type of the worker f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message message a message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param worker a {@code ProgressDialogWorker} that is executed when this method is called f@0: * @param millisToDecideToPopup the millisecond to let to the worker before popping the dialog up f@0: * @return an integer indicating whether the task was completed or it was interrupted by the user f@0: */ f@0: public static int showProgressDialog(Component parentComponent, String message,final ProgressDialogWorker worker, int millisToDecideToPopup){ f@0: JProgressBar progressBar = worker.bar; f@0: Object displayObjects[] = {message, progressBar}; f@0: final JOptionPane optPane = new JOptionPane(displayObjects); f@0: optPane.setOptionType(DEFAULT_OPTION); f@0: optPane.setOptions(new Object[] {PROGRESS_DIALOG_CANCEL_OPTION}); f@0: /* ctrl key will hush the TTS */ f@0: optPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL,InputEvent.CTRL_DOWN_MASK),"shut_up"); f@0: optPane.getActionMap().put("shut_up", SpeechUtilities.getShutUpAction()); f@0: f@0: final JDialog dialog = optPane.createDialog(parentComponent, resources.getString("dialog.speech_option_pane.download")); f@0: SpeechUtilities.changeTabListener(optPane,dialog); f@0: f@0: worker.setDialog(dialog); f@0: worker.execute(); f@0: try { f@0: Thread.sleep(millisToDecideToPopup); f@0: } catch (InterruptedException ie) { f@0: throw new RuntimeException(ie); //should never happen f@0: } f@0: if(worker.isDone()) f@0: return OK_OPTION; f@0: f@0: NarratorFactory.getInstance().speak(message); f@0: SoundFactory.getInstance().startLoop(SoundEvent.EDITING); f@0: dialog.setVisible(true); f@0: SoundFactory.getInstance().stopLoop(SoundEvent.EDITING); f@0: if( optPane.getValue() == null || f@0: optPane.getValue() == PROGRESS_DIALOG_CANCEL_OPTION || f@0: Integer.valueOf(CLOSED_OPTION).equals(optPane.getValue())){ f@0: worker.cancel(true); f@0: return CANCEL_OPTION; f@0: } f@0: return OK_OPTION; f@0: } f@0: f@0: /** f@0: * Shows a check box dialog to select the modifiers of a given property f@0: * f@0: * @param parentComponent the parent {@code Component} for the dialog f@0: * @param message message a message displayed in the dialog, such text is also uttered by the {@code Narrator} f@0: * @param modifierTypes the different types of modifiers that are available for a given property f@0: * @param modifierIndexes the initial selection of modifiers as the dialog is shown f@0: * @return a new set with the modifier indexes selected by the user f@0: */ f@0: public static Set showModifiersDialog(Component parentComponent, String message, List modifierTypes, Set modifierIndexes){ f@0: JOptionPane optPane = new JOptionPane(); f@0: f@0: JPanel checkBoxPanel = new JPanel(new GridLayout(0, 1)); f@0: final JCheckBox[] checkBoxes = new JCheckBox[modifierTypes.size()]; f@0: for(int i=0;i returnSet = new LinkedHashSet(); f@0: for(int i=0;i the result type returned by this {@code SwingWorker}'s {@code doInBackground} and {@code get} methods f@0: * @param the type used for carrying out intermediate results by this {@code SwingWorker}'s {@code publish} and {@code process} methods f@0: */ f@0: public static abstract class ProgressDialogWorker extends SwingWorker { f@0: /** f@0: * Creates a new ProgressDialogWorker f@0: */ f@0: public ProgressDialogWorker(){ f@0: bar = new JProgressBar(); f@0: bar.setIndeterminate(true); f@0: } f@0: f@0: private void setDialog(JDialog dialog){ f@0: this.dialog = dialog; f@0: } f@0: f@0: @Override f@0: protected void done() { //executed in EDT when the work is done f@0: if(dialog != null) f@0: dialog.dispose(); f@0: } f@0: f@0: private JDialog dialog; f@0: private JProgressBar bar; f@0: } f@0: f@0: f@0: }