I have the following code:
package in.res.num.tapb.ui;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
class MainClass extends JPanel {
public MainClass() {
Registration registration = new Registration();
ButtonPanel buttonPanel = new ButtonPanel();
buttonPanel.setRegistration(registration);
buttonPanel.setBorder(BorderFactory.createTitledBorder("Button Panel"));
registration.setBorder(BorderFactory.createTitledBorder("Registration Panel"));
setLayout(new BorderLayout());
add(registration, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Registration");
frame.getContentPane().add(new MainClass());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
@SuppressWarnings("serial")
private class ButtonPanel extends JPanel {
private Registration registration;
public ButtonPanel() {
setLayout(new GridLayout(1, 0, 10, 0));
for (final String keyText : Registration.KEY_TEXTS) {
JButton btn = new JButton(keyText);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (registration != null) {
registration.swapView(keyText);
}
}
});
add(btn);
}
}
public void setRegistration(Registration registration) {
this.registration = registration;
}
}
private static class Registration extends JPanel {
private static final Dimension PREF_SIZE = new Dimension(450, 300);
public static final String USER_AGREEMENT = "User Agreement";
public static final String USER_INFO = "User Information";
public static final String ENROLLMENT = "Enrollment";
public static final String[] KEY_TEXTS = { USER_AGREEMENT, USER_INFO, ENROLLMENT };
private CardLayout cardlayout = new CardLayout();
private JPanel cards = new JPanel(cardlayout);
public Registration() {
cards.add(createUserAgreePanel(), USER_AGREEMENT);
cards.add(createUserInfoPanel(), USER_INFO);
cards.add(createEnrollmentPanel(), ENROLLMENT);
setLayout(new BorderLayout());
add(cards, BorderLayout.CENTER);
}
private JPanel createEnrollmentPanel() {
JPanel enrol = new JPanel();
enrol.setSize(new Dimension(400, 200));
enrol.add(new JLabel("Enrollment"));
return enrol;
}
private JPanel createUserAgreePanel() {
JPanel userAgree = new JPanel();
userAgree.setSize(new Dimension(200, 300));
userAgree.add(new JLabel("User Agreement"));
return userAgree;
}
private JPanel createUserInfoPanel() {
JPanel userInfo = new JPanel();
userInfo.setSize(new Dimension(300, 400));
userInfo.add(new JLabel("User Information"));
return userInfo;
}
public void swapView(String key) {
cardlayout.show(cards, key);
}
}
}
As you can see I want to change the size on button click. Is it possible? The above code is not working, I mean the size is not changing. How can I change the size on fly?
Thanks and regards. Edit:
swap the panel on selecting a row of JList.
getChoicesList().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent listSelectionEvent) {
getViewPanel().changeView(getChoicesList().getSelectedIndex());
getChoicePanel().changeView(Constants.PanelInfo.valueOf(getEngine().getChoiceList().get(getChoicesList().getSelectedIndex()).getEnumName()).getDimensionForScrollPaneOfChoicePanel());
((MainFrame) getTopLevelAncestor()).pack();
}
});
ViewPanel#changeView(), this swaps the panel:
public void changeView(int index) {
removeAll();
getPanels().get(index).setPreferredSize(Constants.PanelInfo.valueOf(getEngine().getChoiceList().get(index).getEnumName()).getDimensionForViewPanel());
add(getPanels().get(index));
}
As a concrete example of camickr's answer, the program below shows how to rely on the preferred size of components as the frame is resized via
pack()
. The faux content is a series of labels, but anyJComponent
will do. As the content is recreated dynamically, it can change according to other conditions in the program.After resizing the JFrame, use: yourframe.validate();
You should never use setSize() when using a layout manager. It is the job of the layout manager to determine the size. You can provide hints to the layout manager by setting the peferred or minimum or maximum sizes. However it is not recommend that you do this since components and panels should be displayed at their preferred size which will be determined by the layout manager you are using. If you did override the size then the code should be:
However, this still won't work the way you want because the job of the CardLayout is to determine the largest size of all panels added to the panel using a CardLayout. So when you swap from panel to panel you don't get the size of each individual panel. This is s better experience for the user because the user doesn't want to see the frame size keep changing every time they hit a button.
If you did want to have the frame change size every time you click on a button then the basic code would be:
Then the layout manager of the main panel will observe the preferred size of the newlay added panel.