im trying to build a GUI for my Java application. I dynamically add JPanels, which are a \"row\" in my GUI. Under the List of the Panels there is a button to add a new Panel
It's difficult to assertain from your code snippet exactly where you might be having problems.
public class DynamicPanelList {
public static void main(String[] args) {
new DynamicPanelList();
}
public DynamicPanelList() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JPanel mainList;
public TestPane() {
setLayout(new BorderLayout());
mainList = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.weighty = 1;
mainList.add(new JPanel(), gbc);
add(new JScrollPane(mainList));
JButton add = new JButton("Add");
add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JPanel panel = new JPanel();
panel.add(new JLabel("Hello"));
panel.setBorder(new MatteBorder(0, 0, 1, 0, Color.GRAY));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
mainList.add(panel, gbc, 0);
validate();
repaint();
}
});
add(add, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
You really need to provide a SSCCE which would allow us to diagnose the problems you are having.
Personally, and this will depend on you requirements, a better layout manager might be VerticalLayout
from SwingLabs SwingX libraries.
You probably forgot to call revalidate()
on your listContainer
(and you made a bunch of syntax errors). BoxLayout
does not do a great job in my opinion, but that is not the matter here.
Here is a small demo code which seems to work quite well:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestScollpane {
private int i;
private JPanel listContainer;
private void initUI() {
final JFrame frame = new JFrame(TestScollpane.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
listContainer = new JPanel();
listContainer.setLayout(new BoxLayout(listContainer, BoxLayout.Y_AXIS));
frame.add(new JScrollPane(listContainer), BorderLayout.CENTER);
JButton button = new JButton("Add");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final JPanel newPanel = new JPanel();
newPanel.add(new JLabel("Label " + i++));
listContainer.add(newPanel);
listContainer.revalidate();
// Scroll down to last added panel
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
newPanel.scrollRectToVisible(newPanel.getBounds());
}
});
}
});
frame.add(button, BorderLayout.PAGE_END);
frame.setSize(300, 200);
frame.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestScollpane().initUI();
}
});
}
}