【问题标题】:Getting input from a JOptionPane which is in a JDialog从 JDialog 中的 JOptionPane 获取输入
【发布时间】:2018-06-17 23:20:38
【问题描述】:

出于涉及外观精美的组件的目的,我编写了一个函数,用于在 JDialog 中创建和显示 JOptionPane。现在,我需要从该 JDialog 获取输入,但我不能。有没有一种方法可以让我在不扩展 JDialog 或 JOptionPane 的情况下从该 JDialog 获取输入? (我也不能使用 UIManager 来改变 JDialog 的外观,这就是我首先遇到问题的原因)

public static final Color WHITE = Color.WHITE;
public static final Color RED = Color.RED;
public static final Color LIGHTER_RED = new Color(255, 0, 0, 100);
public static final Color LIGHT_RED = new Color(255, 0, 0, 160);
public static final Color DARK_BLUE = new Color(22, 44, 66);

public static final Font GEORGIA_BOLD_12 = new Font("Georgia", Font.BOLD, 12);

public static final BasicStroke STROKE_0 = new BasicStroke(0);

private static void recursivePaint(Container ct) {
    for (Component c : ct.getComponents()) {
        if (c instanceof Container) {
            c.setBackground(DARK_BLUE);
            c.setForeground(WHITE);
            recursivePaint((Container) c);
        }
    }
}

public static int showInputDialog(final Container parent) {
    int portNumber = 0;

    final JLabel label = new JLabel("Enter an Open Port: ", SwingConstants.LEFT);
    label.setOpaque(true);
    label.setBackground(DARK_BLUE);
    label.setForeground(WHITE);

    final JButton button = new JButton("OK") {

        private static final long serialVersionUID = -4808194362293478299L;

        @Override
        public int getWidth() {
            return 51;
        }

        @Override
        public int getHeight() {
            return 26;
        }

        @Override
        public void paintComponent(final Graphics g) {
            final Graphics2D g2d = (Graphics2D) g;
            g2d.clearRect(0, 0, getWidth(), getHeight());
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2d.setStroke(STROKE_0);
            g2d.setColor(LIGHTER_RED);
            if (this.getModel().isRollover()) {
                g2d.setColor(LIGHT_RED);
            }
            if (this.getModel().isPressed()) {
                g2d.setColor(RED);
            }
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.setColor(RED);
            g2d.drawRect(0, 0, getWidth(), getHeight());
            g2d.setColor(WHITE);
            g2d.setFont(GEORGIA_BOLD_12);
            g2d.drawString("CONFIRM", 10, 18);
        }
    };
    button.addActionListener(e -> {
        //GET THE INPUT OF JOPTIONPANE TEXTFIELD
        //portNumber = getTextOfJOptionPane();
        SwingUtilities.getWindowAncestor((Component) e.getSource()).setVisible(false);
        SwingUtilities.getWindowAncestor((Component) e.getSource()).dispose();
    });

    final JOptionPane optionPane = new JOptionPane(label, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_OPTION, null, new JButton[] {button}, button);
    optionPane.setWantsInput(true);
    optionPane.setOpaque(true);
    optionPane.setBackground(DARK_BLUE);
    optionPane.getInputValue();
    recursivePaint(optionPane);
    final JDialog d = optionPane.createDialog(parent, "Open port required!");
    d.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    d.setContentPane(optionPane);
    d.pack();
    d.setLocationRelativeTo(parent);
    d.setVisible(true);
    return portNumber;
}

提前致谢。

JOptionPane on Windows

【问题讨论】:

  • 仔细查看the JavaDocs for JOptionPane,尤其是"Direct Use:"示例。基本上,对话框关闭后,您将像往常一样从JOptionPane 获取值,但您需要“手动”执行此操作
  • 谢谢!。我刚刚做了并得到了一个想法,但是那里有一行我不明白,“pane.set.Xxxx(...); // Configure”是什么意思? JOptionPane 没有这样的方法。你能描述一下如何“配置”一个 JOptionPane
  • 等等,这仅仅意味着设置方法吗?我很困惑:(
  • 是的,这意味着您需要自己配置对话框。特别是setWantsUnputsetSelectionValuessetInitialSelectionValue,您可以通过getInputValue获取输入值。看看JOptionPane.showInputDialog的源代码,它将演示对话框是如何由类本身构建的
  • 长话短说-您将不得不手动设置它,包括提供JTextField,当按下“确认”按钮时,您需要从@获取值987654332@ 并调用setInputValue - 为什么,因为JOptionPane 没有公开JTextField 用于基类中的输入,这似乎是由外观委托应用的

标签: java swing user-interface


【解决方案1】:

由于JOptionPane 没有公开复制此功能所需的所有功能,因此您将不得不采取更多控制措施。

“适当的”路径是提供您自己的自定义外观和感觉委托,但这似乎需要做很多额外的工作才能控制JTextField

相反,您可以通过 message 参数将 JLabelJTextField 都传递给 OptionPane,例如包含在单个 JPanel 中...

public static final Color WHITE = Color.WHITE;
public static final Color RED = Color.RED;
public static final Color LIGHTER_RED = new Color(255, 0, 0, 100);
public static final Color LIGHT_RED = new Color(255, 0, 0, 160);
public static final Color DARK_BLUE = new Color(22, 44, 66);

public static final Font GEORGIA_BOLD_12 = new Font("Georgia", Font.BOLD, 12);

public static final BasicStroke STROKE_0 = new BasicStroke(0);

public static int showInputDialog(final Container parent) {
    int portNumber = 0;

    final JLabel label = new JLabel("Enter an Open Port: ", SwingConstants.LEFT);
    label.setForeground(WHITE);

    JPanel panel = new JPanel(new GridLayout(2, 1));
    panel.setOpaque(true);
    panel.setBackground(DARK_BLUE);
    JTextField inputField = new JTextField(10);
    panel.add(label);
    panel.add(inputField);

    final JButton button = new JButton("OK") {

        private static final long serialVersionUID = -4808194362293478299L;

        @Override
        public int getWidth() {
            return 51;
        }

        @Override
        public int getHeight() {
            return 26;
        }

        @Override
        public void paintComponent(final Graphics g) {
            final Graphics2D g2d = (Graphics2D) g;
            g2d.clearRect(0, 0, getWidth(), getHeight());
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2d.setStroke(STROKE_0);
            g2d.setColor(LIGHTER_RED);
            if (this.getModel().isRollover()) {
                g2d.setColor(LIGHT_RED);
            }
            if (this.getModel().isPressed()) {
                g2d.setColor(RED);
            }
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.setColor(RED);
            g2d.drawRect(0, 0, getWidth(), getHeight());
            g2d.setColor(WHITE);
            g2d.setFont(GEORGIA_BOLD_12);
            g2d.drawString("CONFIRM", 10, 18);
        }
    };
    final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_OPTION, null, new JButton[]{button}, button);
    button.addActionListener(e -> {
        //GET THE INPUT OF JOPTIONPANE TEXTFIELD
        optionPane.setInputValue(inputField.getText());
        optionPane.setValue(JOptionPane.OK_OPTION);
    });

    optionPane.setOpaque(true);
    optionPane.setBackground(DARK_BLUE);
    final JDialog d = optionPane.createDialog(parent, "Open port required!");
    d.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    d.setContentPane(optionPane);
    d.pack();
    d.setLocationRelativeTo(parent);
    d.setVisible(true);
    System.out.println(optionPane.getValue());
    System.out.println(optionPane.getInputValue());
    return portNumber;
}

所以。此外,我还做了一些额外的更改。在ActionListener 中,我将操作的“值”设置为OK_OPTION 并调用setInputValue。调用setValue 很重要,否则不会应用inputValue,因为它认为你已经“取消”了对话。

我不知道你的对话框在你的系统上是什么样的,但这是我在我的系统上的样子......

这就是为什么不建议覆盖 getHeightgetWidth 之类的内容的原因

【讨论】:

  • 该死,在 Windows 操作系统上看起来不错。从来没有想过它会在其他操作系统上看起来如此扭曲。关于如何在不覆盖 getHeight 和 getWidth 的情况下正确创建自定义外观按钮的任何建议?我现在真的可以使用一些建议。
  • 是的,要么按预期使用 API,要么自己编写:P
  • 我在我的答案中添加了一个 imgur 链接。那是 JOptionPane 的图像。当使用 recursivePaint 函数时(你没有因为我忘记添加它但现在它被添加了)它看起来没问题。但我确信有更好的方法来创建自定义按钮。所以,如果除了这种方式之外,您还有其他选择,我绝对愿意听到它们。再次感谢您的帮助。程序终于完成了。 :)
猜你喜欢
  • 1970-01-01
  • 2012-01-10
  • 2014-02-11
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-02
  • 1970-01-01
相关资源
最近更新 更多