I am trying to find a way to create a list of JPanels which have no Layout manager.
I found several examples on SO providing solutions to the 'scrollable JPanel list' problem. More specifically, I started from this thread and worked on it.
My current problem is that I am having issues when I remove the layout from the JPanels in the list.
They get added correctly but the scrollbar does not appear when needed, and the panels start overlapping.
Note: I know that layouts are heavily preferred but I find it more straightforward to work with pure X, Y coordinates and a mockup program. Please do not bash me for this...
Here is a small working example (taken and modified from this comment):
import java.awt.BorderLayout;
import java.awt.Color;
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;
import javax.swing.border.MatteBorder;
public class JScrollPanels {
private int i;
private JPanel listContainer;
private void initUI() {
final JFrame frame = new JFrame(JScrollPanels.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.setLayout(null);
newPanel.setSize(272, 110);
JLabel name = new JLabel("Name " + i++);
name.setBounds(18, 13, 84, 21);
newPanel.setBorder(new MatteBorder(0, 0, 1, 0, Color.GRAY));
JLabel date = new JLabel("12/11/2014");
date.setBounds(10, 44, 123, 21);
JButton btn= new JButton(">");
btn.addActionListener( new NameListener(name, date) );
btn.setBounds(205, 44, 48, 30);
newPanel.add(name);
newPanel.add(date);
newPanel.add(btn);
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(272, 300);
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 JScrollPanels().initUI();
}
});
}
public class NameListener implements ActionListener {
private JLabel name;
private JLabel date;
public NameListener(JLabel name, JLabel date) {
this.name = name;
this.date = date;
}
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked " + name.getText() + " on " + date.getText());
}
}
}
EDIT:
Fixed by using this:
final JPanel newPanel = new JPanel(){
@Override
public Dimension getPreferredSize() {
return new Dimension(272, 110);
}
};
Thanks, mKorbel!