在 JOptionPane 中重新绘制组件

Repaint components in JOptionPane

我有部分视图在 JOptionPane 中显示文本字段。还有一个按钮"other"。单击它后,我需要 JOptionPane 重绘自身并显示一些隐藏的文本字段。

我的文本字段使用 GridLayout。我在按钮侦听器中尝试了 revalidate()repaint() 方法,但它们没有做任何改变。

validate() 方法有效,但所有组件的大小都太小。在网格面板中调整大小似乎有误。在我的原始代码中,一些组件只是隐藏起来了。我没有 setPrefferedSize()getPrefferedSize() 因为我读错了,但无法弄清楚如何正确调整大小。

我把我的代码做的尽可能简单,只是视图的一部分。

public class AddView {

    private JFrame parentFrame;
    private JPanel addPanel;
    private JPanel gd;

    private JLabel nameLabel;
    private JLabel surName;
    private JLabel skype;

    private JTextField nameTField;
    private JTextField surNameTField;
    private JTextField skypeTField;

    private JButton otherButton;

    public AddView(JFrame parent) {
        this.parentFrame = parent;
        initComponents();
    }

    private void initComponents() {
        addPanel = new JPanel(new BorderLayout());
        gd = new JPanel(new GridLayout(2, 2, 0, 5));

        nameLabel = new JLabel("Name");
        surName = new JLabel("Surname");
        skype = new JLabel("Skype");

        nameTField = new JTextField();
        surNameTField = new JTextField();
        skypeTField = new JTextField();

        otherButton = new JButton("Other");

        gd.add(nameLabel);
        gd.add(nameTField);
        gd.add(surName);
        gd.add(surNameTField);

        addPanel.add(gd, BorderLayout.CENTER);
        addPanel.add(otherButton, BorderLayout.SOUTH);

        otherButton.addActionListener(new OtherFieldsAction());
    }

    public int showAddPane() {
        return JOptionPane.showConfirmDialog(parentFrame, addPanel, "Add Contact", JOptionPane.OK_CANCEL_OPTION);
    }

    private class OtherFieldsAction implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            gd.setLayout(new GridLayout(3, 2, 0, 5));
            gd.add(skype);
            gd.add(skypeTField);
            // gd.revalidate(); not work
            // gd.repaint();
            gd.validate();

        }
    }
}

这是 JOptionPane

当我点击 "other" 按钮时,我得到了这个结果

但我需要像这样调整大小才能得到它

能否请教一下如何正确重绘。

您可能需要调用添加组件的 setPreferredSize() 以获得您需要的正确尺寸。

也许 Window#pack() 方法会起作用:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class AddView2 {
  private JFrame parentFrame;
  private JPanel addPanel;
  private JPanel gd;

  private JLabel nameLabel;
  private JLabel surName;
  private JLabel skype;

  private JTextField nameTField;
  private JTextField surNameTField;
  private JTextField skypeTField;

  private JButton otherButton;

  public AddView2(JFrame parent) {
    this.parentFrame = parent;
    initComponents();
  }

  private void initComponents() {
    addPanel = new JPanel(new BorderLayout());
    gd = new JPanel(new GridLayout(2, 2, 0, 5));

    nameLabel = new JLabel("Name");
    surName = new JLabel("Surname");
    skype = new JLabel("Skype");

    nameTField = new JTextField();
    surNameTField = new JTextField();
    skypeTField = new JTextField();

    otherButton = new JButton("Other");

    gd.add(nameLabel);
    gd.add(nameTField);
    gd.add(surName);
    gd.add(surNameTField);

    addPanel.add(gd, BorderLayout.CENTER);
    addPanel.add(otherButton, BorderLayout.SOUTH);

    otherButton.addActionListener(new OtherFieldsAction());
  }

  public int showAddPane() {
    return JOptionPane.showConfirmDialog(parentFrame, addPanel, "Add Contact", JOptionPane.OK_CANCEL_OPTION);
  }

  private class OtherFieldsAction implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
      gd.setLayout(new GridLayout(3, 2, 0, 5));
      gd.add(skype);
      gd.add(skypeTField);
      // gd.revalidate(); not work
      // gd.repaint();
      // gd.validate();
      SwingUtilities.getWindowAncestor((Component) e.getSource()).pack();
    }
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
    new AddView2(f).showAddPane();
  }
}