Gridbag layout resizes when I add components - java

I am new to gridbag layout. While doing testing, I noticed that my grid bag layout does not retain specific size (grid size) when I add components.
I want my application to be compatible with various screensizes, so I can not hardcode the size in advance.
What could I be doing wrong. Am I not understanding the way grids should be designed?
Update: All I had to do was to set the preferred Size of the component. It they stopped growing arbitrarily.
code:
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class Main extends JFrame {
// Drawing panels
private JPanel panelLeft;
private JPanel panelCenter;
private JPanel panelRight;
private JPanel panelTopCenter, panelTopLeft, panelTopRight;
private JPanel storyPanel;
// Layout
private GridBagLayout gridBadLayout;
private static final String DEFAULT_GAME_WORLD_NAME = "DefaultWorldName";
// Constructor
public Main() {
initializePanels();
}
/*
* Initializes look and feel of the window. No components should be
* initalized in this because controller would like to lazily initialize
* them once data is avialable.
*/
private void initializePanels() {
this.setTitle("World Maker");
this.setBounds(55, 5, 600, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(Color.LIGHT_GRAY);
gridBadLayout = new GridBagLayout();
panel.setLayout(gridBadLayout);
GridBagConstraints c = new GridBagConstraints();
this.add(panel);
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.3;
c.weighty = 0.1;
c.anchor = GridBagConstraints.NORTH;
c.fill = GridBagConstraints.BOTH;
panelTopLeft = new JPanel();
panelTopLeft.setBackground(Color.WHITE);
panelTopLeft.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelTopLeft, c);
c.gridx = 1;
c.gridwidth = 3;
panelTopCenter = new JPanel();
panelTopCenter.setBackground(Color.WHITE);
panelTopCenter.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelTopCenter, c);
c.gridx = 4;
c.gridwidth = 1;
panelTopRight = new JPanel();
panelTopRight.setBackground(Color.WHITE);
panelTopRight.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelTopRight, c);
c.gridx = 0;
c.gridy = 1;
c.gridheight = 3;
c.gridwidth = 1;
c.weightx = 0.3;
c.weighty = 1.0;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
panelLeft = new JPanel();
panelLeft.setBackground(Color.WHITE);
panelLeft.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelLeft, c);
c.gridx = 1;
c.gridy = 1;
c.gridheight = 3;
c.gridwidth = 3;
c.weightx = 1.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
panelCenter = new JPanel();
panelCenter.setBackground(Color.WHITE);
panelCenter.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelCenter, c);
c.gridx = 4;
c.gridy = 1;
c.gridheight = 3;
c.gridwidth = 1;
c.weightx = 0.3;
c.weighty = 1.0;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.BOTH;
panelRight = new JPanel();
panelRight.setBackground(Color.WHITE);
panelRight.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelRight, c);
addRandomComponents();
this.setVisible(true);
panel.setOpaque(true);
this.validate();
}
private void addRandomComponents() {
//add JButton to panelTopLeft
panelTopLeft.add(new JButton("TEST1"));
panelTopLeft.add(new JButton("TEST2"));
panelTopLeft.add(new JButton("TEST3"));
//add combo box to panelRight
panelRight.add(new JComboBox(Arrays.asList("TEST1", "TEST2").toArray()));
}
public static void main(String[] args) {
Main main = new Main();
}
}
Screenshots:
1) Before I add any components
2) After I add components (see the left top panel)

This happens because there is no preferred size set for the components. Once set, components do not grow larger than the size.
panelTopLeft.setPreferredSize(new Dimension(100, 0));
Complete fixed code.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class Main extends JFrame {
// Drawing panels
private JPanel panelLeft;
private JPanel panelCenter;
private JPanel panelRight;
private JPanel panelTopCenter, panelTopLeft, panelTopRight;
private JPanel storyPanel;
// Layout
private GridBagLayout gridBadLayout;
private static final String DEFAULT_GAME_WORLD_NAME = "DefaultWorldName";
// Constructor
public Main() {
initializePanels();
}
/*
* Initializes look and feel of the window. No components should be
* initalized in this because controller would like to lazily initialize
* them once data is avialable.
*/
private void initializePanels() {
this.setTitle("World Maker");
this.setBounds(55, 5, 600, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(Color.LIGHT_GRAY);
gridBadLayout = new GridBagLayout();
panel.setLayout(gridBadLayout);
GridBagConstraints c = new GridBagConstraints();
this.add(panel);
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.3;
c.weighty = 0.1;
c.anchor = GridBagConstraints.NORTH;
c.fill = GridBagConstraints.BOTH;
panelTopLeft = new JPanel();
panelTopLeft.setBackground(Color.WHITE);
panelTopLeft.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelTopLeft, c);
c.gridx = 1;
c.gridwidth = 3;
panelTopCenter = new JPanel();
panelTopCenter.setBackground(Color.WHITE);
panelTopCenter.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelTopCenter, c);
c.gridx = 4;
c.gridwidth = 1;
panelTopRight = new JPanel();
panelTopRight.setBackground(Color.WHITE);
panelTopRight.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelTopRight, c);
c.gridx = 0;
c.gridy = 1;
c.gridheight = 3;
c.gridwidth = 1;
c.weightx = 0.3;
c.weighty = 1.0;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
panelLeft = new JPanel();
panelLeft.setBackground(Color.WHITE);
panelLeft.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelLeft, c);
c.gridx = 1;
c.gridy = 1;
c.gridheight = 3;
c.gridwidth = 3;
c.weightx = 1.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
panelCenter = new JPanel();
panelCenter.setBackground(Color.WHITE);
panelCenter.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelCenter, c);
c.gridx = 4;
c.gridy = 1;
c.gridheight = 3;
c.gridwidth = 1;
c.weightx = 0.3;
c.weighty = 1.0;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.BOTH;
panelRight = new JPanel();
panelRight.setBackground(Color.WHITE);
panelRight.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.add(panelRight, c);
addRandomComponents();
this.setVisible(true);
panel.setOpaque(true);
this.validate();
}
private void addRandomComponents() {
//add JButton to panelTopLeft
panelTopLeft.add(new JButton("TEST1"));
panelTopLeft.add(new JButton("TEST2"));
panelTopLeft.add(new JButton("TEST3"));
panelTopLeft.setPreferredSize(new Dimension(100, 0));
//add combo box to panelRight
panelRight.add(new JComboBox(Arrays.asList("TEST1", "TEST2").toArray()));
}
public static void main(String[] args) {
Main main = new Main();
}
}

Related

Java GridBagLayout does not fill frame horizontally

I am writing the GUI for a chat program. I can't seem to get the scroller to fill the frame horizontally and vertically and the messageInput to fill the frame horizontally. This is how it looks:
import javax.swing.*;
import java.awt.*;
public class GUI extends JFrame{
private JPanel panel;
private JEditorPane content;
private JTextField messageInput;
private JScrollPane scroller;
private JMenu options;
private JMenuBar mb;
private JMenuItem item;
public GUI(){
/** This is the frame**/
this.setPreferredSize(new Dimension(380,600));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
/** This is where the context shows up **/
content = new JEditorPane();
content.setEditable(false);
/** Scroller that shows up in the context JEditorPane **/
scroller = new JScrollPane(content);
c.weightx = 0.0;
c.weighty = 0.0;
c.gridx = 0;
c.gridy = 0;
panel.add(scroller, c);
/** This is where you type your message **/
messageInput = new JTextField();
c.weightx = 0.0;
c.weighty = 0.0;
c.gridx = 0;
c.gridy = 1;
c.weighty = 0.5;
panel.add(messageInput, c);
mb = new JMenuBar();
options = new JMenu("Options");
mb.add(options);
this.setJMenuBar(mb);
this.add(panel);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) {
new GUI();
}
}
get the scroller to fill the frame horizontally and vertically and the messageInput to fill the frame horizontally.
You want to fill in both directions, so set
c.fill = GridBagConstraints.BOTH; // not HORIZONTAL
The next part is to fix the weights, which will tell how much space to allocate for each component (relatively):
scroller = new JScrollPane(content);
c.weightx = 0.5;
c.weighty = 1.0;
c.gridx = 0;
c.gridy = 0;
panel.add(scroller, c);
messageInput = new JTextField();
c.weightx = 0.5;
c.weighty = 0.0;
c.gridx = 0;
c.gridy = 1;
panel.add(messageInput, c);
weightx should be a non-zero value to allow the components to stretch horizontally. weighty should be non-zero for the editor, but not for the text field so that it won't take extra vertical space (in this case you don't need to set c.fill = GridBagConstraints.HORIZONTAL for it).

JFrame Buttons and GridBagConstraints

Why are my constraints for my buttons not working? I looked at the Java Docs and am doing the same thing the tutorials are doing, but for me the buttons stay the same regardless of what gridx, y, width, or fill I use. Any ideas? Here's my code:
class MyWindow
{
public static void main(String [] arg)
{
MyJFrame f = new MyJFrame("My GUI 2015");
f.setVisible(true);
f.setSize(10, 20);
f.add(f.p);
}
}
and
public class MyJFrame extends JFrame {
public JPanel p;
JButton close = new JButton("close");
JButton drawing = new JButton("drawing");
JButton image = new JButton("image");
JButton browser = new JButton("browser");
public MyJFrame(String title) {
super(title);
p = new JPanel();
buildButtons();
}
void buildButtons() {
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(0,40,0,150);
c.gridx = 0;
c.gridy = 0;
p.add(drawing, c);
c.gridx = 2;
c.gridy = 0;
p.add(close, c);
c.insets = new Insets(50,225,50,150);
c.gridx = 0;
c.gridy = 1;
p.add(image, c);
c.insets = new Insets(0,125,0,125);
c.gridx = 0;
c.gridy = 100;
c.gridwidth = 3;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(browser, c);
}
}
The LayoutManager for the container is not specified in your current code (the default for a JPanel is FlowLayout). If you wish to use a GridBagLayout on the container, you must explicitly specify the LayoutManager:
p = new JPanel(new GridBagLayout());
//or
p.setLayout(new GridBagLayout());

ActionListener in JFrames

There is an issue with the code where the ActionListener will not pick up on any action when i call upon it with the buttons. I have done this before but this is my first time attempting a GridBagLayout and it doesn't seem to be working correctly. The GUI is fully functional. What could I do to get the ActionListener to work? Here is the entire class.
package body;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class mainFrame extends JFrame implements ActionListener{
final static boolean shouldFill = true;
final static boolean shouldWeightX = true;
final static boolean RIGHT_TO_LEFT = false;
static String string = "default";
static JButton one, two, three, four, five, six, seven, eight, nine, zero;
static JButton plus, minus, multiply, divide, equals;
public void init() {
one.setActionCommand("one");
one.addActionListener(this);
two.setActionCommand("two");
two.addActionListener(this);
three.setActionCommand("three");
three.addActionListener(this);
four.setActionCommand("four");
four.addActionListener(this);
five.setActionCommand("five");
five.addActionListener(this);
six.setActionCommand("six");
six.addActionListener(this);
seven.setActionCommand("seven");
seven.addActionListener(this);
eight.setActionCommand("eight");
eight.addActionListener(this);
nine.setActionCommand("nine");
nine.addActionListener(this);
zero.setActionCommand("zero");
zero.addActionListener(this);
plus.setActionCommand("plus");
plus.addActionListener(this);
minus.setActionCommand("minus");
minus.addActionListener(this);
multiply.setActionCommand("multiply");
multiply.addActionListener(this);
divide.setActionCommand("divide");
divide.addActionListener(this);
equals.setActionCommand("equals");
equals.addActionListener(this);
}
public static void addComponentsToPane(Container pane) {
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
c.fill = GridBagConstraints.HORIZONTAL;
}
if (shouldWeightX) {
c.weightx = 0.5;
}
JLabel display = new JLabel(string);
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 0;
c.gridy = 0;
pane.add(display, c);
one = new JButton("1");
c.weightx = 0.5;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
pane.add(one, c);
two = new JButton("2");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 1;
c.gridy = 1;
pane.add(two, c);
three = new JButton("3");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 2;
c.gridy = 1;
pane.add(three, c);
plus = new JButton("+");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 3;
c.gridy = 1;
pane.add(plus, c);
four = new JButton("4");
c.weightx = 0.5;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 2;
pane.add(four, c);
five = new JButton("5");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 1;
c.gridy = 2;
pane.add(five, c);
six = new JButton("6");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 2;
c.gridy = 2;
pane.add(six, c);
minus = new JButton("-");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 3;
c.gridy = 2;
pane.add(minus, c);
seven = new JButton("7");
c.weightx = 0.5;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 3;
pane.add(seven, c);
eight = new JButton("8");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 1;
c.gridy = 3;
pane.add(eight, c);
nine = new JButton("9");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 2;
c.gridy = 3;
pane.add(nine, c);
multiply = new JButton("*");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 3;
c.gridy = 3;
pane.add(multiply, c);
zero = new JButton("0");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 0;
c.gridy = 4;
pane.add(zero, c);
equals = new JButton("Equals");
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 1.0;
c.gridx = 1;
c.gridwidth = 2;
c.gridy = 4;
pane.add(equals, c);
divide = new JButton("/");
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_END;
c.weightx = 0.5;
c.gridx = 3;
c.gridy = 4;
pane.add(divide, c);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "one") {
System.out.println("hello");
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Besides the == and equals I pointed out, you never call init(), which initializes your action commands.
Also note, you class is already a JFrame. Either use the class JFrame or use the instance JFrame.
You should fix the above problem so that you can properly call your init() method.
Try this
private static void createAndShowGUI() {
mainFrame frame = new mainFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
addComponentsToPane(frame.getContentPane());
frame.init(); <<<<<================== Don't forget about meeeee!
frame.pack();
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if ("one".equals(e.getActionCommand())) {
System.out.println("hello");
}
}
Also you should be following Java naming convention. Class names begin with capital letters. So mainFrame → MainFrame

Java Swing - realising a layout with LayeredPane

I have a question regarding making a specific Layout, first I'll show examples then I will add some extra clarification.
Layout when Friends and Messages are closed:
Layout when Friends and Messages are opened:
I intend to make this layout with Java Swing.
My intention is to firstly have the Frame divided in three areas, the top menu row, the main panel and the bottom menu row.
I was thinking of using a BorderLayout for this part.
Then the Friends and Messages buttons should be toggle button's, and on toggle they should show an overlay on top of the mainpanel (or whatever is there), containing a friend list and a message area. I realised I need to use a LayeredPane somehow for this.
Another important part is that the Layout should be viewable in any size, that is the user may resize the application and it will be used on a various amount of resolutions, so I don't really want anything with a fixed width and height.
But I am really lost as how to combine this, so therefore I ask your help.
Hopefully I have explained enough about the situation.
Regards.
this could be about overlay, because JPanel can contains other JComponents
use JLayer (Java7) based on JXLayer(Java6),
use GlassPane with JComponents layed to rellative to....
easiest could be to use JDialog(undecorated) layed to Point (setLocation(int, int)), setVisible() must be wrapped into invokeLater
I will use gridBagLayout.
Here is small example including button which hide your yellow panels:
package Core;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GridBagLayoutDemo {
public static void addComponentsToPane(Container pane) {
pane.setLayout(new GridBagLayout());
add1row(pane);
addmainRow(pane);
addLastRow(pane);
}
private static void addLastRow(Container pane) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 3;
c.anchor = GridBagConstraints.PAGE_END;
JPanel bottonPanel = new JPanel();
bottonPanel.setBackground(Color.BLUE);
bottonPanel.setLayout(new GridBagLayout());
pane.add(bottonPanel, c);
JPanel messagePanel = new JPanel();
messagePanel.setBackground(Color.GRAY);
messagePanel.add(new JLabel("MESSAGES"));
c.fill = GridBagConstraints.VERTICAL;
c.anchor = GridBagConstraints.LINE_END;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
bottonPanel.add(messagePanel, c);
}
private static void addmainRow(Container pane) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 1;
c.weightx = 1;
c.weighty = 1;
c.anchor = GridBagConstraints.CENTER;
JPanel mainManel = new JPanel();
mainManel.setBackground(Color.GREEN);
mainManel.setLayout(new GridBagLayout());
pane.add(mainManel, c);
final JPanel friendListPanel = new JPanel();
friendListPanel.setBackground(Color.YELLOW);
friendListPanel.add(new JLabel("FRIEND LIST"));
c.fill = GridBagConstraints.NONE;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 1;
c.anchor = GridBagConstraints.FIRST_LINE_END;
mainManel.add(friendListPanel, c);
c.fill = GridBagConstraints.NONE;
c.gridx = 0;
c.gridy = 1;
c.weightx = 0;
c.weighty = 0;
c.anchor = GridBagConstraints.CENTER;
JButton button = new JButton("On/Off");
mainManel.add(button, c);
final JPanel messageAreaPanel = new JPanel();
messageAreaPanel.setBackground(Color.YELLOW);
messageAreaPanel.add(new JLabel("MESSAGE PANEL"));
c.fill = GridBagConstraints.NONE;
c.gridx = 0;
c.gridy = 2;
c.weightx = 1;
c.weighty = 1;
c.anchor = GridBagConstraints.LAST_LINE_END;
mainManel.add(messageAreaPanel, c);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
friendListPanel.setVisible(!friendListPanel.isVisible());
messageAreaPanel.setVisible(!messageAreaPanel.isVisible());
}
});
}
private static void add1row(Container pane) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.PAGE_START;
Panel headerPanel = new Panel();
headerPanel.setLayout(new GridBagLayout());
headerPanel.setBackground(Color.BLUE);
pane.add(headerPanel, c);
JPanel quitPanel = new JPanel();
quitPanel.setBackground(Color.GRAY);
quitPanel.add(new JLabel("QUIT"));
c.fill = GridBagConstraints.VERTICAL;
c.anchor = GridBagConstraints.LINE_START;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
headerPanel.add(quitPanel, c);
JPanel friendsPanel = new JPanel();
friendsPanel.setBackground(Color.GRAY);
friendsPanel.add(new JLabel("FRIENDS"));
c.fill = GridBagConstraints.VERTICAL;
c.anchor = GridBagConstraints.LINE_END;
c.gridx = 1;
c.gridy = 0;
headerPanel.add(friendsPanel, c);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame);
// uncoment to use full screen
// frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.setSize(new Dimension(400, 400));
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

How to align left or right inside GridBagLayout cell?

I see that GridBagLayout positions it's children with center alignment within cells. How to align left or right?
UPDATE
Constructing code (I know I could reuse c)
// button panel
JPanel button_panel = new JPanel();
button_panel.add(ok_button);
button_panel.add(cancel_button);
// placing controls to dialog
GridBagConstraints c;
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
add(inputSource_label, c);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
add(inputSource_combo, c);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 1;
add(output_label, c);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
add(output_combo, c);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 2;
add(button_panel, c);
When using GridBagLayout for a tabular display of JLabel : JTextField, I like to have a method that makes my GridBagConstraints for me based on the x, y position. For example something like so:
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
The following code makes a GUI that looks like this:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class GridBagEg {
private static void createAndShowGui() {
PlayerEditorPanel playerEditorPane = new PlayerEditorPanel();
int result = JOptionPane.showConfirmDialog(null, playerEditorPane,
"Edit Player", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
// TODO: do something with info
for (PlayerEditorPanel.FieldTitle fieldTitle :
PlayerEditorPanel.FieldTitle.values()) {
System.out.printf("%10s: %s%n", fieldTitle.getTitle(),
playerEditorPane.getFieldText(fieldTitle));
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class PlayerEditorPanel extends JPanel {
enum FieldTitle {
NAME("Name"), SPEED("Speed"), STRENGTH("Strength");
private String title;
private FieldTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
};
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private Map<FieldTitle, JTextField> fieldMap = new HashMap<FieldTitle, JTextField>();
public PlayerEditorPanel() {
setLayout(new GridBagLayout());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Player Editor"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
GridBagConstraints gbc;
for (int i = 0; i < FieldTitle.values().length; i++) {
FieldTitle fieldTitle = FieldTitle.values()[i];
gbc = createGbc(0, i);
add(new JLabel(fieldTitle.getTitle() + ":", JLabel.LEFT), gbc);
gbc = createGbc(1, i);
JTextField textField = new JTextField(10);
add(textField, gbc);
fieldMap.put(fieldTitle, textField);
}
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
public String getFieldText(FieldTitle fieldTitle) {
return fieldMap.get(fieldTitle).getText();
}
}
In this example, I display the JPanel in a JOptionPane, but it could just as easily be displayed in a JFrame or JApplet or JDialog or ...
For example
public class DimsPanel extends JPanel
{
public static void main(String[] args){
JFrame main = new JFrame("Dims");
JPanel myPanel = new DimsPanel();
main.setContentPane(myPanel);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setSize(400, 400);
main.setLocationRelativeTo(null);
main.setVisible(true);
}
JButton ok_button = new JButton("OK"), cancel_button = new JButton("Cancel");
JLabel inputSource_label = new JLabel("Input source:"),
output_label = new JLabel("Output:");
JComboBox inputSource_combo = new JComboBox(new String[]{"A", "B", "C"}),
output_combo = new JComboBox(new String[]{"A", "B", "C"});
public DimsPanel(){
super(new BorderLayout());
Box main = new Box(BoxLayout.Y_AXIS);
Dimension labelsWidth = new Dimension(100, 0);
JPanel inputPanel = new JPanel(new BorderLayout());
inputSource_label.setPreferredSize(labelsWidth);
inputPanel.add(inputSource_label, BorderLayout.WEST);
inputPanel.add(inputSource_combo);
JPanel outputPanel = new JPanel(new BorderLayout());
output_label.setPreferredSize(labelsWidth);
outputPanel.add(output_label, BorderLayout.WEST);
outputPanel.add(output_combo);
// button panel
JPanel button_panel = new JPanel();
button_panel.add(ok_button);
button_panel.add(cancel_button);
main.add(inputPanel);
main.add(outputPanel);
add(main, BorderLayout.NORTH);
add(button_panel);
}
}
You can run and see it. Resizing works like a charm and the layout code has only 18 lines.
The only disadvantage is that you need to specify the width of the labels by hand. If you really don't want to see setPreferredSize() in the code, then be my guest and go with GridBag. But I personally like this code more.

Categories