Here is a pretty simple layout (code included) where non-uniform column sizes could improve packing.
Is there a way, using a single GridBagLayout
, to get the components to fit together nicely?
I thought that using a width of 3 for the top two components, then a width of 5 & 1 for the next two rows would influence the alignment, but I cannot get it to stay flush. My current solution (not included) is to create a sub panel with the red and green panels.
import javax.swing.*;
import java.awt.*;
public class GridBagWrong{
public static void main(String[] args){
JPanel content = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
//create five panels to layout.
JPanel a = new JPanel();
a.setPreferredSize( new Dimension(300, 30) );
a.setBorder( BorderFactory.createLineBorder(Color.BLUE) );
JPanel b = new JPanel();
b.setPreferredSize( new Dimension(300, 30) );
b.setBorder( BorderFactory.createLineBorder(Color.BLUE) );
JPanel c = new JPanel();
c.setPreferredSize( new Dimension(500, 30) );
c.setBorder( BorderFactory.createLineBorder(Color.GREEN) );
JPanel d = new JPanel();
d.setPreferredSize( new Dimension(500, 30) );
d.setBorder( BorderFactory.createLineBorder(Color.GREEN) );
JPanel e = new JPanel();
e.setPreferredSize( new Dimension(100, 60) );
e.setBorder( BorderFactory.createLineBorder(Color.RED) );
//place them in a gridbaglayout.
gbc.gridwidth = 3;
content.add(a, gbc);
gbc.gridx = 3;
content.add(b, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 5;
content.add(c, gbc);
gbc.gridy = 2;
content.add(d, gbc);
gbc.gridy = 1;
gbc.gridx = 5;
gbc.gridheight = 2;
gbc.gridwidth = 1;
content.add(e, gbc);
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane( content );
frame.pack();
frame.setVisible(true);
}
}
CodePudding user response:
Following up on my comment from above you can use:
//JPanel content = new JPanel(new GridBagLayout());
GridBagLayout gbl = new GridBagLayout();
int[] columns = new int[6];
Arrays.fill(columns, 100);
gbl.columnWidths = columns;
JPanel content = new JPanel(gbl);
The above code states each of the 6 columns will have a minimum width of 100.
If a component is added to a column with gridwidth = 1
, then the preferred size of that component will be used as the width of the column.
So now when you specify gridwidth = 3
it has a meaning because the layout can use either the width of a component added to the columnn or the minimum width to determine the actual size of the component.
CodePudding user response:
For some reason GridBagLayout
is adding addition space to it's calculations, but I'm not sure why. At first I thought it was the LineBorder
, but when I modified your code to remove the border, it still didn't work...
I don't know where the extra spacing on the right is coming from (it's probably really obvious, but I can't see it)
Sooo, this is one of those moments where I "flip the table" and "rage quite" and instead, "hack it"
Since there seems to be a disconnect between the first and second row, for some reason, I combined the two panels from the first row into a single panel and got rid of all the gridwidth
s (more or less)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
//create five panels to layout.
JPanel a = new LayoutPane();
a.setForeground(Color.BLUE);
a.setPreferredSize(new Dimension(300, 30));
JPanel b = new LayoutPane();
b.setPreferredSize(new Dimension(300, 30));
b.setForeground(Color.BLUE);
JPanel c = new LayoutPane();
c.setPreferredSize(new Dimension(500, 30));
c.setForeground(Color.GREEN);
JPanel d = new LayoutPane();
d.setPreferredSize(new Dimension(500, 30));
d.setForeground(Color.GREEN);
JPanel e = new LayoutPane();
e.setPreferredSize(new Dimension(100, 60));
e.setForeground(Color.RED);
JPanel topPane = new JPanel(new GridBagLayout());
//place them in a gridbaglayout.
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
topPane.add(a, gbc);
gbc.gridx ;
topPane.add(b, gbc);
gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(topPane, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.WEST;
add(c, gbc);
gbc.gridy = 2;
add(d, gbc);
gbc = new GridBagConstraints();
gbc.gridy = 1;
gbc.gridx ;
gbc.gridheight = 2;
gbc.anchor = GridBagConstraints.EAST;
add(e, gbc);
}
}
public class LayoutPane extends JPanel {
public LayoutPane() {
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(getForeground());
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
String text = getWidth() "x" getHeight();
FontMetrics fm = g2d.getFontMetrics();
int x = (getWidth() - fm.stringWidth(text)) / 2;
int y = ((getHeight() - fm.getHeight()) / 2) fm.getAscent();
g2d.drawString(text, x, y);
g2d.dispose();
}
}
}