【问题标题】:How do I make a JOptionPane dropdown that has a preset option that is not choosable?如何制作具有不可选择的预设选项的 JOptionPane 下拉列表?
【发布时间】:2021-11-14 18:35:34
【问题描述】:

假设我正在制作一个程序来跟踪人们最喜欢的食物。我有一个下拉菜单,例如:

String foods = { "Pizza", "Burgers", "Pasta", "Bacon" };
String favoriteFood = JOptionPane.showInputDialog(null, "What is your favorite food?", "Choice", JOptionPane.QUESTION_MESSAGE, null, foods, foods[0]));
JOptionPane.showMessageDialog(null, favoriteFood);
            

如何在下拉菜单中创建一个类似于“立即选择...”的部分,但如果您单击“立即选择...”,它不会成为您的选择?谢谢!

【问题讨论】:

  • 你滚动你自己的对话框
  • 我不认为你可以通过JOptionPane 轻松做到这一点。但是为什么不创建自己的JDialog,使用自定义JComboBox,结合自定义渲染器,如下所示:tips4java.wordpress.com/2008/10/18/combo-box-prompt
  • 好的。谢谢!
  • 1) 阅读 JOptionPane API。有代码显示 JOptionPane 类的“直接使用”,因此您可以访问JOptionPane 组件。 2) 签出:Swing Utils。 If 将向您展示如何访问 JOptionPane 的组合框。 3)按照上面的链接设置组合框的渲染器。

标签: java swing joptionpane


【解决方案1】:

你可以这样做

String[] foods = { "Pizza", "Burgers", "Pasta", "Bacon" };
JComboBox<String> cb = new JComboBox<String>(foods);
cb.getModel().setSelectedItem("Choose now...");

cb.addHierarchyListener(hEv -> {
    if((hEv.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && cb.isShowing()) {
        JButton ok = SwingUtilities.getRootPane(cb).getDefaultButton();
        ok.setEnabled(cb.getSelectedIndex() >= 0);
        cb.addActionListener(aEv -> ok.setEnabled(cb.getSelectedIndex() >= 0));
}   });

JPanel p = new JPanel(new GridLayout(0, 1, 0, 8));
p.add(new JLabel("What is your favorite food?"));
p.add(cb);

int choice = JOptionPane.showConfirmDialog(null,
    p, "Choice", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);

JOptionPane.showMessageDialog(null,
    choice == JOptionPane.OK_OPTION? cb.getSelectedItem(): "no choice");

第一个挑战是设置一个不属于可选选项的(预)选定值。当您在不可编辑的JComboBox 上调用setSelectedItem 时,它将拒绝模型之外的任何值。但是,我们可以直接在模型上设置选择的值,比如cb.getModel().setSelectedItem("Choose now...");

然后,为了确保我们不会将此初始选择与实际选择混淆,我们必须禁用“确定”按钮,直到从列表中做出选择 (cb.getSelectedIndex() &gt;= 0)。为了获得“确定”按钮本身,我们等到整个 AWT 层次结构构建完成并获得默认按钮。

【讨论】:

    【解决方案2】:

    使用JOptionPane 的可能解决方案如下所示。在此代码中,JDialog 或多或少是手动创建的。然后从JOptionPane 中提取“确定”按钮和可用选项,并且“确定”按钮仅在选择“从...中选择”以外的任何内容时启用。

    String[] foods = new String[]{"Choose now...", "Pizza", "Burgers", "Pasta", "Bacon"};
    JOptionPane pane = new JOptionPane("What is your favorite food?",  JOptionPane.QUESTION_MESSAGE,
            JOptionPane.OK_CANCEL_OPTION, null,
            null, null);
    
    pane.setWantsInput(true);
    pane.setSelectionValues(foods);
    pane.setInitialSelectionValue(foods[0]);
    
    // create the dialog and select the initial value
    JDialog dialog = pane.createDialog( null, "title" );
    pane.selectInitialValue();
    
    // find the OK Button and disable it by default
    JPanel buttonPanel = (JPanel) pane.getComponent( 1 );
    JButton ok = (JButton) buttonPanel.getComponent( 0 );
    ok.setEnabled( false );
    // find the JComboBox (the panel holding the available options)
    JPanel childPanel = (JPanel) ((JPanel) pane.getComponent( 0 )).getComponent( 0 );
    JPanel innerPanel = (JPanel) childPanel.getComponent( 1 );
    JComboBox options = (JComboBox) innerPanel.getComponent( 1 );
    // add an action listener to the JComboBox; enable the OK button if a valid option is selected
    options.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if ( options.getSelectedIndex() == 0 ) {
                ok.setEnabled( false );
            } else {
                ok.setEnabled( true );
            }
        }
    });
    
    // show the dialog
    dialog.show(); // <--- note this one is deprecated, should probably use: dialog.setVisible( true );
    dialog.dispose();
    
    // get the selected value
    String value = pane.getInputValue().toString();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 2010-12-06
      • 2016-02-21
      • 1970-01-01
      相关资源
      最近更新 更多