Force JOptionPane to Stay Open

2019-08-20 03:40发布

问题:

My application is constructed as follows:

  • Main window allows user to select CSV file to be parsed
  • JOptionPane appears after a CSV file is selected and the JOptionPane contains a drop-down menu with various choices; each of which generates a separate window
  • Currently, the JOptionPane closes after a selection is made from the menu and the "OK" button is clicked

I am looking for a way to force the JOptionPane to remain open so that the user can select something different if they want. I would like the JOptionPane to be closed only by clicking the "X" in the upper right corner. I am also open to other possibilities to achieve a similar result if using a JOptionPane isn't the best way to go on this.

Here is the relevant block of code I'm working on:

try 
{
    CSVReader reader = new CSVReader(new FileReader(filePath), ',');

    // Reads the complete file into list of tokens.
    List<String[]> rowsAsTokens = null;

    try 
    {
        rowsAsTokens = reader.readAll();
    } 

    catch (IOException e1) 
    {
        e1.printStackTrace();
    }

    String[] menuChoices = { "option 1", "option 2", "option 3" };

    String graphSelection = (String) JOptionPane.showInputDialog(null, 
            "Choose from the following options...", "Choose From DropDown", 
            JOptionPane.QUESTION_MESSAGE, null, 
            menuChoices, // Array of menuChoices
            menuChoices[0]); // Initial choice

    String menuSelection = graphSelection;

    // Condition if first item in drop-down is selected
    if (menuSelection == menuChoices[0] && graphSelection != null)
    {
        log.append("Generating graph: " + graphSelection + newline);

        option1();          
    }

    if (menuSelection == menuChoices[1] && graphSelection != null)
    {

        log.append("Generating graph: " + graphSelection + newline);

        option2();      
    }

    if (menuSelection == menuChoices[2] && graphSelection != null)
    {
        log.append("Generating graph: " + graphSelection + newline);

        option3();
    }

    else if (graphSelection == null)
    {   
        log.append("Cancelled." + newline);
    }
}

回答1:

I would like for the window with the choices to remain open even after the user has selected an option so that they can select another option if they wish. How do I get the JOptionPane to remain open instead of its default behavior where it closes once a drop-down value is selected?

  • this is basic property, by default JOptionPane is disposed, this isn't possible without dirty hacks, don't do that

  • use JDialog (could, may be undecorated) with proper value for ModalityType

  • you can to use some of variations for Java & Ribbon

  • you can to put desired choices to the JComboBox or JMenu with JMenuItems (very nice of ways) to the JLayer or GlassPane

  • I think that this is standard job for JMenu or JToolBar



回答2:

In either of these option panes, I can change my choice as many times as I like before closing it. The 3rd option pane will show (default to) the value selected earlier in the 1st - the current value.

import java.awt.*;
import javax.swing.*;

class Options {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                Object[] options = {
                    "Option 1",
                    "Option 2",
                    "Option 3",
                    "None of the above"
                };
                JComboBox optionControl = new JComboBox(options);
                optionControl.setSelectedIndex(3);
                JOptionPane.showMessageDialog(null, optionControl, "Option",
                        JOptionPane.QUESTION_MESSAGE);
                System.out.println(optionControl.getSelectedItem());

                String graphSelection = (String) JOptionPane.showInputDialog(
                        null,
                        "Choose from the following options...", 
                        "Choose From DropDown",
                        JOptionPane.QUESTION_MESSAGE, null,
                        options, // Array of menuChoices
                        options[3]); // Initial choice
                System.out.println(graphSelection);

                // show the combo with current value!
                JOptionPane.showMessageDialog(null, optionControl, "Option",
                        JOptionPane.QUESTION_MESSAGE);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

I think Michael guessed right with a JList. Here is a comparison between list & combo.

Note that both JList & JComboBox can use a renderer as seen in the combo. The important difference is that a list is an embedded component that supports multiple selection.



回答3:

The following solution won't give you a drop-down menu but it will allow you to select multiple values.

You can use a JList to store your choices and to use JOptionPane.showInputMessage like this:

JList listOfChoices = new JList(new String[] {"First", "Second", "Third"});
JOptionPane.showInputDialog(null, listOfChoices, "Select Multiple Values...", JOptionPane.QUESTION_MESSAGE);

Using the method getSelectedIndices() on listOfChoices after the JOptionPane.showInputDialog() will return an array of integers that contains the indexes that were selected from the JList and you can use a ListModel to get their values:

int[] ans = listOfChoices.getSelectedIndices();
ListModel listOfChoicesModel = listOfChoices.getModel();
for (int i : ans) {
    System.out.println(listOfChoicesModel.getElementAt(i));
}