tags:

views:

48

answers:

2

I have a sample code :

import java.awt.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;

public class AWT extends JFrame {

    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(600, 450));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.green.darker());

        Button btn_1 = new Button("Button 1");
        btn_1.setBackground(Color.green.darker());
        btn_1.setSize(40, 100);
        Button btn_2 = new Button("Button 2");
        btn_2.setBackground(Color.green.darker());
        btn_2.setSize(40, 100);
        Button btn_3 = new Button("Button 3");
        btn_3.setBackground(Color.green.darker());
        btn_3.setSize(40, 100);

        JPanel players = new JPanel(new GridLayout(1, 3));
        players.add(btn_1);
        players.add(btn_2);
        players.add(btn_3);
        players.setBackground(Color.green.darker());
        players.setPreferredSize(new Dimension(450, 80));

        JPanel game = new JPanel();
        game.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        game.setBackground(Color.green);
        game.setPreferredSize(new Dimension(600, 370));

        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());
        frame.setContentPane(content);
        content.add(players, BorderLayout.NORTH);
        content.add(game, BorderLayout.SOUTH);
        frame.pack();
 frame.setVisible(true);
    }
}

This as a result gives me such a window :

alt text

, while it should result in something more like this :

alt text

Why it is not rendering in this way ?

+2  A: 

GridLayout ignores the buttons' preferred size. Replace

JPanel players = new JPanel(new GridLayout(1, 3));

with

JPanel players = new JPanel(); // default FlowLayout

Addendum: Here's a related example of letting the layout and default preferred sizes do the work. By specifying as few constraints as possible, the appearance adjusts to each platform's look & feel when pack() is invoked.

import java.awt.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;

public class AWT extends JFrame {

    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel players = new JPanel();
        players.add(new GameButton("Button 1"));
        players.add(new GameButton("Button 2"));
        players.add(new GameButton("Button 3"));
        players.setBackground(GameButton.color);

        JPanel game = new JPanel();
        game.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        game.setBackground(Color.green);
        game.setPreferredSize(new Dimension(600, 450));

        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());
        frame.setContentPane(content);
        content.add(players, BorderLayout.NORTH);
        content.add(game, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    private static class GameButton extends JButton {

        private static final Color color = Color.green.darker();
        private static final Font font = new Font("SanSerif", Font.BOLD, 20);
        private String name;

        public GameButton(String name) {
            super(name);
            this.setBackground(color);
            this.setFont(font);
        }
    }
}
trashgod
this is a good solution as well for the layout. though setPreferredSize does the size part of the magic.
Balint Pato
+2  A: 
  1. GridLayout stretches out the compoments added to them directly. I'd use another layout, or if you really want GridLayout checkout the code below.

  2. You have to use setPreferredSize on the buttons as well! (see below)

import java.awt.*;

import javax.swing.*;
import javax.swing.border.BevelBorder;

public class AWT extends JFrame {

public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(600, 450));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.green.darker());

Button btn_1 = new Button("Button 1");
btn_1.setBackground(Color.green.darker());
btn_1.setPreferredSize(new Dimension(40, 100)); 

Button btn_2 = new Button("Button 2");
btn_2.setBackground(Color.green.darker());
btn_2.setPreferredSize(new Dimension(40, 100)); 

Button btn_3 = new Button("Button 3");
btn_3.setBackground(Color.green.darker());
btn_3.setPreferredSize(new Dimension(40, 100));    

GridLayout layout = new GridLayout(1, 3);
JPanel players = new JPanel(layout);
JPanel cell1 = new JPanel();
cell1.add(btn_1);
cell1.setBackground(Color.green.darker());
players.add(cell1);
JPanel cell2 = new JPanel();
cell2.add(btn_2);
cell2.setBackground(Color.green.darker());
players.add(cell2);
JPanel cell3 = new JPanel();
cell3.add(btn_3);
cell3.setBackground(Color.green.darker());
players.add(cell3);
players.setBackground(Color.green.darker());
players.setPreferredSize(new Dimension(450, 80));

JPanel game = new JPanel();
game.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
game.setBackground(Color.green);
game.setPreferredSize(new Dimension(600, 370));

JPanel content = new JPanel();
content.setLayout(new BorderLayout());
frame.setContentPane(content);
content.add(players, BorderLayout.NORTH);
content.add(game, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
Balint Pato
This is very instructive, but I often try to avoid too "heavy" a hand with component attributes. On some platforms, e.g. Mac OS X, `setBackground()` on a `JButton` has no apparent effect; and `setPreferredSize()` can't take into account platform-specific font metrics.
trashgod
that's all true!
Balint Pato