【问题标题】:How can I make a JFrame modal like a JOptionPane?如何制作像 JOptionPane 一样的 JFrame 模式?
【发布时间】:2012-01-05 18:04:33
【问题描述】:

首先,我会提出问题,然后我会解释应用程序。

如何让JFrames 表现得像JOptionPanes? (tutorial didn't help) 即

[Show content >> return a value]。另外我需要它是

[Show the frame >> Ask information >> Modify an object passed as parameter to the constructor >> return something]

我已经让“确定”按钮得到我想要的答案(在控制台中显示),但我不知道在哪里放置 return 语句

我希望函数类似于

public static String getAnswer(Args, Answer)

Args,可能包含字段名称、数据类型、最大长度和

Answer,是要修改的对象,用户给出信息后点击“确定”

总是有争论和答案。例如(看截图,看看我需要如何显示“最复杂”类型的消息,虽然它不完整,因为它需要根据数据类型显示不同类型的组件)。

| Arg                  |   Answer     |
--------------------------------------
| Type   | fldName     |              |
--------------------------------------
| int    | Age:        | 22           |
| String | Name:       | Roger        |
| Date   | Birth:      | 31/10/1989   |

到目前为止,我所做的是显示一个带有所需内容的 JFrame(即对话框)并制作一个按钮以在控制台中显示答案。

如何构建 JFrame?我有 4 个类,其中三个类在屏幕截图下方描述,最后一个类构建一个包含其他三个面板的 JPanel 并将其添加到 JFrame。如果你想看代码click

为什么我不使用 JDialog,因为它需要一个我没有的父框架。我需要从另一个非 java 应用程序中显示它,所以它必须已经是顶部框架。



您可能不想阅读此内容,但如果您有兴趣阅读我正在做的事情,请继续阅读:

我知道,通过使用JOptionPane.showMessageDialog() 等,我的问题可能会得到解决,但我无法弄清楚它是否适合我的需求。 JOptionPane 上显示的内容似乎仅限于我,我不知道如何保持控制或引用我放入其中的孩子,一切都会改变它的行为。

我必须创建五个不同的对话框,将值返回给另一个应用程序(痛苦的 oracle 表单 6i)。对话框的类型有:

  • 打印对话框,显示打印机列表或“导出到文件”选项
  • 消息对话框,显示 html 内容(如电子邮件预览)并带有“确定”按钮。
  • 是/否对话框,要求用户确认,类似于消息对话框。
  • 参数形式,要求用户给出一些信息,它要求的信息,是基于一个select或者一个字符串数组。
  • 值列表,基于 select 语句,显示结果,就像 plsql 开发人员所做的那样。

这是最后一项(Parameter form)的截图,在示例中,每一项都是月份类型,答案将填充其值。

如您所见,框架被 3 个块划分(我将它们分为 3 个类 TopPanelMidPanelBotPanel):分别为消息对话框、用户输入和命令按钮。

TopPanel,从 JScrollPane 扩展并创建一个 JEditorPane,因为它可能显示 html 内容

MidPanel,从 JScrollPane 扩展而来(这个,只为列表中的最后两个对话框创建),并基于表单作为参数传递给用户的对象创建字段,输入到 this,需要在java中进行检查,因为它可以是日期、文本字段或基于select语句的组合框(图中,根据对数据库的查询,有一年中的12个月)。

BotPanel 可以控制 java 对表单的回答,例如参数列表或是/否对话框的回答。该面板会随着各种对话而变化。例如对于是/否对话框,它具有“是”和“否”按钮,这将使 java 返回 true 或 false,但对于参数表单对话框,如果发生,它将返回错误消息,并且 Object 包含以下信息用户选择。

【问题讨论】:

  • JDialog 没有父母是可能的 - see this SO question
  • 为什么不简单地将复杂的 GUI/JPanel 放入 JOptionPane 中?
  • @HovercraftFullOfEels 你觉得太复杂了吗?我应该改变模型吗?我认为它很简单,例如mainPanel{Top{message}, Mid{changingContent}, Bot{changinContent}} 有没有更简单的解决方案?我不是经验丰富的程序员。谢谢。
  • @Roger:不,它并不太复杂,一点也不。在下面运行我的示例,您可以看到使用 JOptionPane 可以轻松完成。

标签: java swing modal-dialog


【解决方案1】:

同样,您可以将任何复杂的 gui 放入 JOptionPane。 JOptionPane show 方法的第二个参数接受一个可以是任何 Swing 组件的 Object。例如:

import java.awt.*;
import java.util.HashMap;
import java.util.Map;

import javax.swing.*;

import com.roots.map.MapPanel.ControlPanel;

public class ComplexDialog extends JPanel {
   public static final String[] COMBO_LABELS = { "Nombre 1",
         "Identificacion 1", "Fecha 1", "Empresa 1", "Nombre 2",
         "Identificacion 2", "Fecha 2", "Empresa 2", "Nombre 3",
         "Identificacion 3", "Fecha 3", "Empresa 3", "Nombre 4",
         "Identificacion 4", "Fecha 4", "Empresa 4", "Nombre 5",
         "Identificacion 5", "Fecha 5", "Empresa 5", "Nombre 6",
         "Identificacion 6", "Fecha 6", "Empresa 6", "Nombre 7",
         "Identificacion 7", "Fecha 7", "Empresa 7" };
   public static final String[] COMBO_ITEMS = { "January", "February", "March",
         "April", "May", "June", "July", "August", "September", "October",
         "November", "December" };
   private JTextArea textarea = new JTextArea(15, 30);
   private Map<String, JComboBox> comboMap = new HashMap<String, JComboBox>();

   public ComplexDialog() {
      textarea.setLineWrap(true);
      textarea.setWrapStyleWord(true);
      for (int i = 0; i < 100; i++) {
         textarea.append("This is a really large text. ");
      }

      JPanel comboPanel = new JPanel(new GridBagLayout());
      for (int i = 0; i < COMBO_LABELS.length; i++) {
         addToComboPanel(comboPanel, COMBO_LABELS[i], i);
      }

      int eb = 5;
      setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(new JScrollPane(textarea));
      add(Box.createVerticalStrut(5));
      JScrollPane comboPanelScroll = new JScrollPane(comboPanel);
      add(comboPanelScroll);

      comboPanelScroll.getViewport().setPreferredSize(
            textarea.getPreferredSize());
   }

   private void addToComboPanel(JPanel comboPanel, String labelText, int index) {
      GridBagConstraints gbc = new GridBagConstraints(0, index, 1, 1, 0.2, 1.0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0,
                  0, 5), 0, 0);
      comboPanel.add(new JLabel(labelText, SwingConstants.RIGHT), gbc);

      gbc = new GridBagConstraints(1, index, 1, 1, 1.0, 1.0,
            GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(
                  0, 0, 0, 0), 0, 0);
      JComboBox combo = new JComboBox(COMBO_ITEMS);
      comboMap.put(labelText, combo);
      comboPanel.add(combo, gbc);

   }

   public String getComboChoice(String key) {
      JComboBox combo = comboMap.get(key);
      if (combo != null) {
         return combo.getSelectedItem().toString();
      } else {
         return "";
      }
   }

   public String getTextAreaText() {
      return textarea.getText();
   }

   public int showDialog() {
      return JOptionPane.showOptionDialog(null, this, "Sirena",
            JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
            new String[] { "Aceptar", "Cancelar" }, "Aceptar");
   }

   private static void createAndShowGui() {
      ComplexDialog dlg = new ComplexDialog();
      int response = dlg.showDialog();
      if (response == 0) {
         System.out.println("JTextArea's text is:");
         System.err.println(dlg.getTextAreaText());

         System.out.println("Combo box selections are: ");
         for (String comboLabel : COMBO_LABELS) {

            System.out.printf("%20s: %s%n", comboLabel, dlg.getComboChoice(comboLabel));
         }
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

【讨论】:

  • 嗨!这样很容​​易。谢谢!现在,我遇到了一个问题,在参数表单中,有些字段是必需的,我该如何控制,如果这些字段没有填写,窗口不会关闭?我知道我必须为每种字段创建文档侦听器或格式化的文本字段,但是“确定”按钮将如何处理这个?,我可以重新制作窗口再次询问信息(显然用以前的输入填充它)但是作为有些字段是基于对数据库的查询构建的,重新查询不会很酷。我应该为此提出一个新问题吗?
  • 伙计!你的速度!!你很快就完成了这个程序!再次感谢:D
  • 不知道你什么时候才能重新连接,所以我提出了一个新问题stackoverflow.com/q/8762004/435394
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 2010-11-03
相关资源
最近更新 更多