I have one JFrame that is set to a GridLayout of size NxN. N is given by the user as a command line at the start of the program. JButtons in an NxN pattern are added to the
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.