简体   繁体   中英

Getting input from a JOptionPane which is in a JDialog

For purposes that involve fancy looking components, I wrote a function that creates and shows a JOptionPane in a JDialog. Now, I need to get input from that JDialog but I can't. Is there a way that will let me get input from that JDialog without extending either JDialog or JOptionPane? (I also can't use UIManager to alter the appearance of JDialog that's why I'm having the problem in the first place)

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;
}

Thanks in advance.

JOptionPane on Windows

Since JOptionPane doesn't expose ALL the functionality you would need to replicate this, you're going to have to take more control.

The "appropriate" path would be to supply your own custom look and feel delegate, but that seems like a lot of extra work just so you can control the JTextField .

Instead, you could pass both the JLabel and JTextField to the OptionPane via the message parameter, contained in a single JPanel , for example...

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;
}

So. In addition, I've made some additional changes. In the ActionListener , I've set the "value" of the operation to OK_OPTION and called setInputValue . It's important that you call setValue , otherwise the inputValue is not applied, because it thinks you've "cancelled" the dialog.

I don't what you're dialog looks like on your system, but this is what it looks like on mine....

🤮

This is why it's ill-advised to override things like getHeight and getWidth

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM