Search code examples
javaswingjoptionpane

Call JOptionPane repaint from internal panel


I have form with combo box. Depends of selected item at this combo box, some fields at form hides and some appears. But size of dialog not auto resized for repainted JPanel of the form. How to fix this?

Sscce.java:

import javax.swing.*;

public class Sscce extends JFrame {
    Sscce() {
        setTitle("Sscce");
        // Sets the behavior for when the window is closed
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().add(new MainPanel());
        pack();
    }
    public static void main(String[] args) {
        Sscce application = new Sscce();
        application.setVisible(true);
    }
}

MainPanel.java:

import javax.swing.*;

public class MainPanel extends JPanel {
    public MainPanel() {
        final DeviceForm form = new DeviceForm();
        JOptionPane.showConfirmDialog(null, form, "Add new device", JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.PLAIN_MESSAGE);
    }
}

DeviceForm.java:

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class DeviceForm extends JPanel implements ActionListener {
    private LinkedHashMap<String, JComponent> fields = new LinkedHashMap<String, JComponent>();
    private HashMap<String, JPanel> borders = new HashMap<String, JPanel>();

    public DeviceForm() {
        String[] versions = {String.valueOf(1), String.valueOf(2),
                String.valueOf(3)};
        JComboBox versionList = new JComboBox(versions);
        versionList.addActionListener(this);
        versionList.setSelectedIndex(0);
        fields.put("Version: ", versionList);

        JTextField textField = new JTextField();
        fields.put("Community: ", textField);

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        for (Map.Entry<String, JComponent> entry : fields.entrySet()) {
            JPanel borderPanel = new JPanel(new java.awt.BorderLayout());
            borderPanel.setBorder(new javax.swing.border.TitledBorder(entry.getKey()));
            borderPanel.add(entry.getValue(), java.awt.BorderLayout.CENTER);
            add(borderPanel);
            borders.put(entry.getKey(), borderPanel);
        }
    }

    /**
     * Repaint form fields for chosen version of SNMP
     * @param e
     */
    public void actionPerformed(ActionEvent e) {
        JComboBox cb = (JComboBox)e.getSource();
        int version = Integer.parseInt((String)cb.getSelectedItem());
        if (version == 1) {    // hide username and password, show community
            JComponent field = borders.get("Username: ");
            if (field != null)
                remove(field);

            field = borders.get("Password: ");
            if (field != null)
                remove(field);


            field = borders.get("Community: ");
            if (field != null)
                add(field);
        }
        else if(version == 3) { // hide community, show username and password
            JComponent field = borders.get("Community: ");
            if (field != null)
                remove(field);

            field = borders.get("Username: ");
            if (field == null)
                addField("Username: ");
            else
                add(field);

            field = borders.get("Password: ");
            if (field == null)
                addField("Password: ");
            else
                add(field);
        }
        validate();
        repaint();
    }

    private void addField(String title) {
        // Create field
        JTextField textField = new JTextField();
        fields.put(title, textField);
        // Border created field
        JPanel borderPanel = new JPanel(new java.awt.BorderLayout());
        borderPanel.setBorder(new javax.swing.border.TitledBorder(title));
        borderPanel.add(textField, java.awt.BorderLayout.CENTER);
        add(borderPanel);
        borders.put(title, borderPanel);
    }
}

Solution

  • The solution is for you to use a CardLayout.

    e.g.,

    import java.awt.CardLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class Sscce2 extends JPanel {
       private static final String COMMUNITY = "Community";
       private static final String PASSWORD = "Password";
       private static final String BLANK = "Blank";
       private static final String[] VERSIONS = {COMMUNITY, PASSWORD, BLANK};
    
       CardLayout cardLayout = new CardLayout();
       JPanel cardHolderPanel = new JPanel(cardLayout);
       JComboBox combobox = new JComboBox(VERSIONS);
       private JPasswordField passwordField = new JPasswordField(15);
       private JTextField communityTextField = new JTextField(15);
    
       public Sscce2() {
          cardHolderPanel.add(createCommunityPanel(), COMMUNITY);
          cardHolderPanel.add(createPasswordPanel(), PASSWORD);
          cardHolderPanel.add(new JLabel(), BLANK);
    
          JPanel comboPanel = new JPanel();
          comboPanel.setLayout(new BoxLayout(comboPanel, BoxLayout.PAGE_AXIS));
          comboPanel.setBorder(BorderFactory.createTitledBorder("Version:"));
          comboPanel.add(combobox);
    
          setLayout(new GridLayout(0, 1));
          add(comboPanel);
          add(cardHolderPanel);
    
          combobox.addActionListener(new ActionListener() {
    
             @Override
             public void actionPerformed(ActionEvent e) {
                String selection = combobox.getSelectedItem().toString();
                cardLayout.show(cardHolderPanel, selection);
             }
          });
       }
    
       public String getCommunityText() {
          return communityTextField.getText();
       }
    
       public char[] getPassword() {
          return passwordField.getPassword();
       }
    
    
       private JPanel createCommunityPanel() {
          JPanel panel = new JPanel();
          panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
          panel.setBorder(BorderFactory.createTitledBorder(COMMUNITY));
          panel.add(communityTextField);
          return panel;
       }
    
    
       private JPanel createPasswordPanel() {
          JPanel panel = new JPanel();
          panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
          panel.setBorder(BorderFactory.createTitledBorder(PASSWORD));
          panel.add(passwordField);
          return panel;
       }
    
    
       private static void createAndShowGui() {
          Sscce2 sscce2 = new Sscce2();
          JOptionPane.showMessageDialog(null, sscce2, "SSCCE 2", JOptionPane.PLAIN_MESSAGE);
    
          System.out.println("Community text: " + sscce2.getCommunityText());
          System.out.println("Password: " + new String(sscce2.getPassword())); // *** never do this!
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }