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: }