JButtons inside JPanels with a GridLayout JFrame
Does each JButton need its own JPanel to use GridLayout?
No. Add and setLayout on JFrame don't do what they appear to. JFrame is Top-Level Containers and it is better to organise your content in JPanels.
You should organize your panels in that form:
----JPanel----------------------------|
| ---LeftPanel--- ---ButtonsPanel--- |
| | | | | |
| | | | | |
| | | | GridLayout(N,N)| |
| | | | | |
| | | | | |
| --------------- ------------------ |
---------------------------------------
Then add JPanel to the JFrame. Also put panels in seperate classes:
class BPanel extends JPanel {
public BPanel() {
GridLayout layout = new GridLayout(N,N, hgap, vgap);
setLayout(layout);
for (int row = 0; row < N; row++){
for (int col = 0; col < N; col++){
JButton b = new JButton ("("+row+","+col+")");
add(b).setLocation(row, col);
b.addActionListener(new ButtonEvent(b, system, row, col));
}
}
}
}
class LeftPanel extends JPanel {
....
}
class MainFrame extends JFrame {
public MainFrame() {
JPanel p = new JPanel();
p.add(new LeftPanel());
p.add(newButtonsPanel());
add(p);
}
}
Here try this code example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LayoutExample extends JFrame
{
private static final String INITIAL_TEXT = "Nothing Pressed";
private static final String ADDED_TEXT = " was Pressed";
private JLabel positionLabel;
private JButton resetButton;
private static int gridSize = 4;
public LayoutExample()
{
super("Layout Example");
}
private void createAndDisplayGUI()
{
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 20));
contentPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2));
JPanel leftPanel = new JPanel();
leftPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2));
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
JPanel labelPanel = new JPanel();
positionLabel = new JLabel(INITIAL_TEXT, JLabel.CENTER);
JPanel buttonLeftPanel = new JPanel();
resetButton = new JButton("Reset");
resetButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
positionLabel.setText(INITIAL_TEXT);
}
});
labelPanel.add(positionLabel);
buttonLeftPanel.add(resetButton);
leftPanel.add(labelPanel);
leftPanel.add(buttonLeftPanel);
contentPane.add(leftPanel);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(gridSize, gridSize, 10, 10));
for (int i = 0; i < gridSize; i++)
{
for (int j = 0; j < gridSize; j++)
{
JButton button = new JButton("(" + i + ", " + j + ")");
button.setActionCommand("(" + i + ", " + j + ")");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JButton but = (JButton) ae.getSource();
positionLabel.setText(
but.getActionCommand() + ADDED_TEXT);
}
});
buttonPanel.add(button);
}
}
contentPane.add(buttonPanel);
setContentPane(contentPane);
pack();
setLocationByPlatform(true);
setVisible(true);
}
public static void main(String[] args)
{
if (args.length > 0)
{
gridSize = Integer.parseInt(args[0]);
}
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new LayoutExample().createAndDisplayGUI();
}
});
}
}
OUTPUT :
One advantage to giving each button (or group of buttons) its own panel is that the nested panel can have a different layout. In this example, each nested ButtonPanel
has the default FlowLayout
, so the button's size remains constant as the enclosing container is resized.