向JOptionPane添加其他自定义按钮

时间:2014-04-13 12:20:44

标签: java user-interface joptionpane

我正在尝试显示一个框架,向用户显示一个项目列表,用户可以从中选择(从组合框菜单中),用户现在可以选择确定以选择所选项目,或按cancel,返回null。这些是给我的默认选项。

这是我的代码段:

Set<ICarOption> optionSet = spec.getCarOptions(category);
// If the category is not mandatory, create a makeshift option object to skip.
if(!category.getMandatory())    optionSet.add(new CarOption("skip"));
ICarOption[] optionArray = optionSet.toArray(new ICarOption[optionSet.size()]);

ICarOption selectedOption = (ICarOption)JOptionPane.showInputDialog(
                frame,
                "Choose one of the following options for Category " + category + ".\n" + 
                "If skip is available, you may choose it to skip this category.",
                "Select a feature",
                JOptionPane.QUESTION_MESSAGE, 
                null, 
                optionArray, 
                optionArray[0]);

此代码在for循环中进行,迭代类别,其中类别并非总是必需的。这意味着如果我想允许用户选择跳过某个类别,我会对组合框执行另一个名为skip的选项,如果选择了该选项,我将相应地跳过它。但这感觉就像一种肮脏的做事方式(在我定义的ICarOption对象的意义上,跳过根本不是一个选项)而且如果类别是强制性的,我宁愿有一个叫做skip的按钮,它是灰色的(不可点击)当类别不是强制性时可用。

我在这里看到了一些例子:http://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html

它似乎表明我应该用自定义的按钮列表替换我的组合框,这不是我想要的。我需要3个按钮(ok,skip,cancel),以及项目列表。

更新: 为了说明我的GUI会是什么样子:

  1. 制作框架。
  2. 在对话框窗口中,您会看到ICarOption对象的组合框(下拉列表)
  3. 窗口上还有3个按钮:OK,SKIP和CANCEL
  4. 如果该类别是强制性的,则SKIP将显示为灰色。
  5. 如果选择“确定”,组合框中当前选定的项目将被赋予selectedOption变量
  6. 如果选择了CANCEL,则选择选项== null
  7. 如果选择了SKIP,则会跳过此类别(继续;)
  8. 这意味着在输入窗口中我需要看到带有项目和3个按钮的组合框。

    - 删除了子问题 -

    UPDATE2: 我刚才意识到我不能使用JButton,因为我需要在actionListener中执行相当多的操作,并且它要求变量是最终的,其中一些不是最终的。

    目前我的代码如下:

    JPanel panel = new JPanel();
    
    JComboBox<ICarOption> optionsBox = new JComboBox<ICarOption>();
    panel.add(optionsBox);
    for(ICarOption option : spec.getCarOptions(category)){
        optionsBox.addItem(option);
    }
    
    Object[] options = { "Select option", "Skip", "Cancel" };
    
    int selected = JOptionPane.showOptionDialog(
                    panel,
                    "Choose one of the following options for Category " + category + ".\n" + 
                    "If skip is available, you may choose it to skip this category.",
                    "Select option",
                    JOptionPane.YES_NO_CANCEL_OPTION, 
                    JOptionPane.INFORMATION_MESSAGE, null, 
                    options, 
                    options[0]);
    
    if(selected == JOptionPane.NO_OPTION)   continue;
    if(selected == JOptionPane.CANCEL_OPTION)   throw new UnavailableException();
    if(selected == JOptionPane.YES_OPTION){
        ...
    }
    

    灵感来自:Java: Custom Buttons in showInputDialog

    这个问题是我现在没有办法控制跳过按钮,因为它是在创建窗口时创建的。

    UPDATE3: 它现在有效,但我并不为我的表现感到自豪..

            JPanel panel = new JPanel();
    
            JComboBox<ICarOption> optionsBox = new JComboBox<ICarOption>();
            panel.add(optionsBox);
            for(ICarOption option : spec.getCarOptions(category)){
                optionsBox.addItem(option);
            }
    
            int selected;
            if(!category.getMandatory()){
                Object[] options = { "Select option", "Cancel", "Skip" };
    
                selected = JOptionPane.showOptionDialog(
                        panel,
                        "Choose one of the following options for Category " + category + ".\n" + 
                        "If skip is available, you may choose it to skip this category.",
                        "Select option",
                        JOptionPane.YES_NO_CANCEL_OPTION, 
                        JOptionPane.INFORMATION_MESSAGE, null, 
                        options, 
                        options[0]);
            }
            else{
                Object[] options = { "Select option", "Cancel" };
    
                selected = JOptionPane.showOptionDialog(
                        panel,
                        "Choose one of the following options for Category " + category + ".\n" + 
                        "If skip is available, you may choose it to skip this category.",
                        "Select option",
                        JOptionPane.YES_NO_OPTION, 
                        JOptionPane.INFORMATION_MESSAGE, null, 
                        options, 
                        options[0]);
            }
    
            // careful! CANCEL_OPTION means skip has been pressed and NO_OPTION means cancel
            if(selected == JOptionPane.CANCEL_OPTION)   continue;
            if(selected == JOptionPane.NO_OPTION)   throw new UnavailableException();
            if(selected == JOptionPane.YES_OPTION){
                ...
            }
    

    肯定有一大堆重复的代码,但这种方式比将skip作为对象传递更有效。

    UPDATE4: 将重复部分更改为以下内容:

            ArrayList<Object> tempList = new ArrayList<Object>();
            int optionType;
    
            tempList.add("Select option");
            tempList.add("Cancel");
            if(!category.getMandatory()){
                tempList.add("Skip");
                optionType = JOptionPane.YES_NO_CANCEL_OPTION;
            }
            else    optionType = JOptionPane.YES_NO_OPTION;
    
            Object[] options = tempList.toArray(new Object[tempList.size()]);
    
            int selected = JOptionPane.showOptionDialog(
                    panel,
                    "Choose one of the following options for Category " + category + ".\n" + 
                            "If skip is available, you may choose it to skip this category.",
                            "Select option",
                            optionType, 
                            JOptionPane.INFORMATION_MESSAGE, null, 
                            options, 
                            options[0]);
    

    所以我将初始化存储在ArrayList中,然后将其转换为数组。这开始看起来对我很好。 :p我不得不说我严重低估了这个问题。我只想更改从添加对象到我的项目列表,以便跳过,跳过按钮。那不知何故花了几个小时做'正确'。

    小编辑(注意用户3469755): 我道歉,我只看了一些以前的编辑,有些东西只是打我。你的原始答案为我提供了我一直想要的东西......使用监听器的问题是我在OK按钮中放了很多功能,但它真正需要做的就是分配所选的项目从下拉列表到参数'selectedOption'。我只需要在showOptionDialog之后添加其余的功能以及处理skip和cancel的部分,因为我确信在那时,已经选择了一个项目并且参数将保存一个对象。我有时会非常密集......

2 个答案:

答案 0 :(得分:3)

您链接的文档很简单:

  

选项:将显示在对话框底部的选项按钮集的更详细说明。 options参数的通常值是一个字符串数组。但参数类型是一个对象数组

因此,您只需要定义一些您选择的JButton,将它们包装在一个数组中(如String数组),然后将它们传递给JOptionPane.showOptionDialog方法。对于JButtons的交互性,您可以使用一些Mouseclick侦听器,例如灰显并使其不可点击(不同的东西!)您可以使用setEnabled()更改JButton属性;

以下是我写的完整示例:

    JButton jbt_ok = new JButton("OK");
    JButton jbt_skip = new JButton("Skip");
    JButton jbt_cancel = new JButton("Cancel");

    boolean greyOutSkipButton = true;

    jbt_ok.addMouseListener(new MouseAdapter() {

        @Override
        public void mouseClicked(MouseEvent e) {
            System.out.println("OK was clicked");

        }
    });

    jbt_cancel.addMouseListener(new MouseAdapter() {

        @Override
        public void mouseClicked(MouseEvent e) {
            System.out.println("Cancel was clicked");

        }
    });

    if(greyOutSkipButton)
        jbt_skip.setEnabled(false);
    else

        jbt_skip.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("Skip was clicked");

            }
        });

    Object[] options = {jbt_ok, jbt_skip, jbt_cancel};

    JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
            JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
            null, options, options[0]);

答案 1 :(得分:2)

主要问题:

我会添加一个单独的按钮,如果类别不是必需的,那么添加ActionListener将跳过该类别并转到下一个类别。

<强> Subquestion:

您需要得到用户的回复。

Object[] options = { "OK", "CANCEL" };
Object answer = JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
null, options, options[0]);

switch ((String) answer){
case "OK":
    //do stuff