Search code examples
javaswingjpanellayout-managercardlayout

Java Swing repack components


I have problem with pack function, when using Card Layout. I created 1 JFrame which include JPanel(in cardlayout) and this JPanel contains two JPanels. ... so when I run my program the windows is resized to biggest JPanel in program and i cant dynamicly resize it.

now screens: my background1(smaller background) class when i run program only with this panel has width like 200 http://i41.tinypic.com/scfi88.jpg when i run my program with added background2 the background gets width of it so it looks for like 400 http://i41.tinypic.com/2lu742x.jpg so it gets width of my background2 panel

In both backgrounds classes i have buttons to return to preview background, but it never resize. I lready used revalidate and repaint functions on thoose action buttons. code: main class and background1 and background2(background codes are big because they are generated by netbeans design mode(they are just few empty components):

public class main extends javax.swing.JFrame {

private JPanel mainPanel;

public main() {
    mainPanel = new JPanel(new CardLayout());
    add(mainPanel);

    Background2 card1 = new Background2(mainPanel);
    Background1 card2 = new Background1(mainPanel);
    mainPanel.add(card1,"card1");
    mainPanel.add(card2,"card2");
    CardLayout cl = (CardLayout) (mainPanel.getLayout());
    cl.show(mainPanel, "card1");
    mainPanel.revalidate();
    mainPanel.repaint();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
}
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new main().setVisible(true);
        }
    });
}
}



public class Background1 extends javax.swing.JPanel {


private JPanel mainPanel;
/**
 * Creates new form HomePanel
 */
public Background1(JPanel panel) {
    mainPanel=panel;
    initComponents();
}


public JPanel getMainPanel() {
    return mainPanel;
}

public void setMainPanel(JPanel mainPanel) {
    this.mainPanel = mainPanel;
}
/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    jTable1 = new javax.swing.JTable();
    left_Panel = new javax.swing.JPanel();
    zakladka1_Button = new javax.swing.JButton();
    background_Panel = new javax.swing.JPanel();
    jScrollPane2 = new javax.swing.JScrollPane();
    jTable2 = new javax.swing.JTable();
    powrot_Button = new javax.swing.JButton();
    jLabel1 = new javax.swing.JLabel();
    jScrollPane3 = new javax.swing.JScrollPane();
    jTable3 = new javax.swing.JTable();

    jTable1.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null}
        },
        new String [] {
            "Title 1", "Title 2", "Title 3", "Title 4"
        }
    ));
    jScrollPane1.setViewportView(jTable1);

    zakladka1_Button.setText("button");
    zakladka1_Button.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            zakladka1_ButtonActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout left_PanelLayout = new javax.swing.GroupLayout(left_Panel);
    left_Panel.setLayout(left_PanelLayout);
    left_PanelLayout.setHorizontalGroup(
        left_PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(left_PanelLayout.createSequentialGroup()
            .addContainerGap()
            .addComponent(zakladka1_Button)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    left_PanelLayout.setVerticalGroup(
        left_PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(left_PanelLayout.createSequentialGroup()
            .addGap(5, 5, 5)
            .addComponent(zakladka1_Button)
            .addGap(433, 433, 433))
    );

    jTable2.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null}
        },
        new String [] {
            "Title 1", "Title 2", "Title 3", "Title 4"
        }
    ));
    jScrollPane2.setViewportView(jTable2);

    javax.swing.GroupLayout background_PanelLayout = new javax.swing.GroupLayout(background_Panel);
    background_Panel.setLayout(background_PanelLayout);
    background_PanelLayout.setHorizontalGroup(
        background_PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(background_PanelLayout.createSequentialGroup()
            .addGap(32, 32, 32)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 452, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(83, Short.MAX_VALUE))
    );
    background_PanelLayout.setVerticalGroup(
        background_PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, background_PanelLayout.createSequentialGroup()
            .addContainerGap(14, Short.MAX_VALUE)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 319, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap())
    );

    powrot_Button.setText("<--");
    powrot_Button.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            powrot_ButtonActionPerformed(evt);
        }
    });

    jLabel1.setText("jLabel1");

    jTable3.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null}
        },
        new String [] {
            "Title 1", "Title 2", "Title 3", "Title 4"
        }
    ));
    jScrollPane3.setViewportView(jTable3);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(left_Panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(layout.createSequentialGroup()
                    .addGap(21, 21, 21)
                    .addComponent(powrot_Button)))
            .addGap(18, 18, 18)
            .addComponent(background_Panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel1)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(18, 18, 18)
            .addComponent(powrot_Button, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(left_Panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addGroup(layout.createSequentialGroup()
            .addComponent(background_Panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(0, 0, Short.MAX_VALUE))
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addComponent(jLabel1)
                    .addGap(115, 115, 115))
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(42, 42, 42))))
    );
}// </editor-fold>                        

private void powrot_ButtonActionPerformed(java.awt.event.ActionEvent evt) {                                              
    CardLayout cl = (CardLayout) (mainPanel.getLayout());
    cl.show(mainPanel, "card1");
    mainPanel.revalidate();
    mainPanel.repaint();
}                                             

private void zakladka1_ButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                 

}                                                



// Variables declaration - do not modify                     
private javax.swing.JPanel background_Panel;
private javax.swing.JLabel jLabel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JTable jTable1;
private javax.swing.JTable jTable2;
private javax.swing.JTable jTable3;
private javax.swing.JPanel left_Panel;
private javax.swing.JButton powrot_Button;
private javax.swing.JButton zakladka1_Button;
// End of variables declaration                   
}

public class Background2 extends javax.swing.JPanel {


private JPanel mainPanel;

public Background2(JPanel panel) {
    mainPanel=panel;
    initComponents();  
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    loginFieldLabel = new javax.swing.JLabel();
    zalogujButton = new javax.swing.JButton();
    loginField = new javax.swing.JTextField();
    passwordField = new javax.swing.JPasswordField();
    logowanieLabel = new javax.swing.JLabel();
    passwordFieldLabel = new javax.swing.JLabel();
    jButton1 = new javax.swing.JButton();

    loginFieldLabel.setText("Login");

    zalogujButton.setText("Zaloguj");
    zalogujButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            zalogujButtonActionPerformed(evt);
        }
    });

    loginField.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            loginFieldActionPerformed(evt);
        }
    });

    passwordField.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            passwordFieldActionPerformed(evt);
        }
    });

    logowanieLabel.setText("Logowanie");

    passwordFieldLabel.setText("Hasło");

    jButton1.setText("jButton1");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

    org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
        .add(layout.createSequentialGroup()
            .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(zalogujButton)
            .add(149, 149, 149))
        .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                    .addContainerGap()
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                        .add(logowanieLabel)
                        .add(layout.createSequentialGroup()
                            .add(56, 56, 56)
                            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                .add(passwordFieldLabel)
                                .add(loginFieldLabel))
                            .add(26, 26, 26)
                            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                                .add(loginField)
                                .add(passwordField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 193, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))))
                .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                    .add(105, 105, 105)
                    .add(jButton1)))
            .addContainerGap(190, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        .add(layout.createSequentialGroup()
            .addContainerGap()
            .add(logowanieLabel)
            .add(29, 29, 29)
            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                .add(loginField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(loginFieldLabel))
            .add(28, 28, 28)
            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                .add(passwordFieldLabel)
                .add(passwordField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
            .add(33, 33, 33)
            .add(zalogujButton)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
            .add(jButton1)
            .addContainerGap(101, Short.MAX_VALUE))
    );
}// </editor-fold>                        

private void zalogujButtonActionPerformed(java.awt.event.ActionEvent evt) {                                              

}                                             

private void loginFieldActionPerformed(java.awt.event.ActionEvent evt) {                                           
    // TODO add your handling code here:
}                                          

private void passwordFieldActionPerformed(java.awt.event.ActionEvent evt) {                                              
    // TODO add your handling code here:
}                                             

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    CardLayout cl = (CardLayout) (mainPanel.getLayout());
    cl.show(mainPanel, "card2");
    mainPanel.revalidate();
    mainPanel.repaint();
}                                        



// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
private javax.swing.JTextField loginField;
private javax.swing.JLabel loginFieldLabel;
private javax.swing.JLabel logowanieLabel;
private javax.swing.JPasswordField passwordField;
private javax.swing.JLabel passwordFieldLabel;
private javax.swing.JButton zalogujButton;
// End of variables declaration                   
}

Edit:

CardLayout cl = (CardLayout) (mainPanel.getLayout());
cl.show(mainPanel, "card1");
l.preferredLayoutSize(mainPanel);//l = ShowingSizeCardLayout i added here prints on dim.width and dim.height 
mainPanel.revalidate();

output:

width: 509
height: 323
width: 1203
height: 537

but it is always 509 323.


Solution

  • The default behaviour of CardLayout is to set the container's preferred size as the component that is showing size plus insets.

    You should subclass CardLayout and override preferredLayoutSize method:

    class ShowingSizeCardLayout extends CardLayout {
    
        public Dimension preferredLayoutSize(Container container) {
    
            Insets insets = container.getInsets();
    
            Dimension dim = null;
    
            for (Component component : container.getComponents()) {
                if (component.isVisible()) {
                    dim = component.getPreferredSize();
                }
            }
    
            dim.width += insets.left + insets.right;
            dim.height += insets.top + insets.bottom;
    
            return dim;
    
        }
    }
    

    This will do, but add code to check for null pointers.