Undesired outcome using GridBagLayout - java

I've been trying to learn by Youtube videos, but there must be something I missing about GridBagLayout.
Basically what I expect is 4 buttons, one below another, with an height of 2 grids, but it seems that no matter what value I set gridheight, the buttons stay the same size
Compilable code :
package test;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class Test{
public static void main(String []args){
System.out.println("Hello World");
JFrame jay = new JFrame("test");
JPanel jp = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JButton j1 = new JButton("Button 1");
JButton j2 = new JButton("Button 22222222222222");
JButton j3 = new JButton("Button 333333");
JButton j4 = new JButton("4");
gc.gridx = 0; gc.gridy = 0;
gc.insets = new Insets(5,10,5,10);
gc.gridheight = 2; //This is where the problem is;
gc.fill = GridBagConstraints.BOTH;
jp.add(j1,gc);
gc.gridx = 0; gc.gridy = 2;
jp.add(j2,gc);
gc.gridx = 0; gc.gridy = 4;
jp.add(j3,gc);
gc.gridx = 0; gc.gridy = 6;
jp.add(j4,gc);
jay.add(jp);
jay.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jay.setSize(300,350);
jay.setVisible(true);
}
}
Also if someone explain me what determines the size of the grids? is it just the component size?

gridheight specifies the number of rows that a component will expand, assuming that there are components in those rows (any empty row will automatically be sized to 0)
how would I go about achieving taller buttons then? adding blank components?
One possible solution is to use ipady which is added to the component's preferredSize property (you can also use ipadx for width)
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JButton j1 = new JButton("Button 1");
JButton j2 = new JButton("Button 22222222222222");
JButton j3 = new JButton("Button 333333");
JButton j4 = new JButton("4");
gc.insets = new Insets(5, 10, 5, 10);
gc.ipady = 50;
gc.gridwidth = GridBagConstraints.REMAINDER;
gc.fill = GridBagConstraints.BOTH;
add(j1, gc);
add(j2, gc);
add(j3, gc);
add(j4, gc);
}
}
}
Have a look at How to Use GridBagLayout for more details

Related

GridBagLayout with glue : no fixed row height

I would like to create a panel, to which I can dynamically add sub-panels with fixed height. I tried using a glue component, but it does not work. I would like to achieve that the sub-panels are visible at the top of the gridbaglayout. Side problem is that when I keep adding sub-panels, they start to overlap because the JScrollPane isn't adjusting. However, when I resize the frame, both problems are solved.
At this moment I don't see where I went wrong. Why does the glue component not take up the vertical space to push the side panels to the top?
This is my SSCCE code:
import javax.swing.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import jrdb.data.ProcessingCommand;
public class ProcessingPipelineBuilderSSCCE extends JFrame {
/**
*
*/
private static final long serialVersionUID = 2413084448601918744L;
private JPanel interiorPanel = null;
private GridBagConstraints gbc = null;
private Component glue = null;
public ProcessingPipelineBuilderSSCCE() {
super("SSCCE");
this.getContentPane().setLayout(new BorderLayout());
gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = GridBagConstraints.PAGE_START;
JPanel pipelineBuilder = new JPanel();
pipelineBuilder.setLayout(new GridLayout(0, 1, 0, 0));
interiorPanel = new JPanel(new GridBagLayout());
interiorPanel.setBorder(BorderFactory.createLineBorder(Color.red));
JScrollPane scrollPane = new JScrollPane(interiorPanel);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(500,300));
pipelineBuilder.add(scrollPane);
JButton btnNew = new JButton("Add new panel");
btnNew.setPreferredSize(new Dimension(500, 30));
btnNew.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (glue!=null) {
interiorPanel.remove(glue);
} else {
glue = Box.createGlue();
}
gbc.gridy = gbc.gridy + 1;
interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
interiorPanel.add(glue,gbc);
interiorPanel.validate();
interiorPanel.repaint();
}
});
this.getContentPane().add(btnNew, BorderLayout.PAGE_START);
this.getContentPane().add(pipelineBuilder,BorderLayout.CENTER);
}
public class PipelineStep extends JPanel {
int number;
public PipelineStep (int n) {
super();
JOptionPane.showMessageDialog(interiorPanel, "adding new panel");
this.number = n;
this.setLayout(new FlowLayout());
JLabel lbl = new JLabel(new Integer(this.number).toString());
lbl.setPreferredSize(new Dimension(45,45));
lbl.setFont(lbl.getFont().deriveFont(26));
this.add(lbl);
this.setPreferredSize(new Dimension(450, 50));
this.setBorder(BorderFactory.createLineBorder(Color.green));
}
}
public static void main (String args[]) {
ProcessingPipelineBuilderSSCCE frame = new ProcessingPipelineBuilderSSCCE();
frame.pack();
frame.setVisible(true);
}
}
Why does the glue component not take up the vertical space to push the side panels to the top?
The "glue" component only has meaning when used with the BoxLayout. It has no effect with the GridBagLayout.
So my suggestion is to forget about the GridBagLayout and use the BoxLayout.
The easiest way to do this is to convert "interiorPanel" to use a vertical Box and just add your PipelineStep instances to this panel.
Try this. However, you will notice that the panels will still increase in size until the scroll pane is full, at which time you will see scrollbars appear. This is because the BoxLayout will resize components up to the maximum size of the component. So to prevent this resizing you could override the getMaximumSize() method of your PipelineStep class:
#Override
public Dimension getMaximumSize()
{
return getPreferredSize();
}
Or, another option is to use a "wrapper" panel for your "interiorPanel". Something like:
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(interiorPanel, BorderLayout.PAGE_START);
//JScrollPane scrollPane = new JScrollPane(interiorPanel);
JScrollPane scrollPane = new JScrollPane(wrapper);
BorderLayout.PAGE_START respects the preferred height of the component added to it so the "interiorPanel" will always be displayed at it preferred height and scrollbars will appear when the viewport of the scroll pane is full.
I modified you code using the "wrapper" approach.
import javax.swing.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
//import jrdb.data.ProcessingCommand;
public class SSCCE1 extends JFrame {
/**
*
*/
private static final long serialVersionUID = 2413084448601918744L;
// private JPanel interiorPanel = null;
private Box interiorPanel = null;
private GridBagConstraints gbc = null;
private Component glue = null;
public SSCCE1() {
super("SSCCE");
this.getContentPane().setLayout(new BorderLayout());
gbc = new GridBagConstraints();
//gbc.insets = new Insets(5, 5, 0, 5);
//gbc.fill = GridBagConstraints.HORIZONTAL;
//gbc.gridx = 0;
//gbc.gridy = 0;
//gbc.weightx = 1.0;
//gbc.weighty = 1.0;
//gbc.anchor = GridBagConstraints.PAGE_START;
JPanel pipelineBuilder = new JPanel();
pipelineBuilder.setLayout(new GridLayout(0, 1, 0, 0));
// interiorPanel = new JPanel(new GridBagLayout());
interiorPanel = Box.createVerticalBox();
interiorPanel.setBorder(BorderFactory.createLineBorder(Color.red));
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(interiorPanel, BorderLayout.PAGE_START);
// JScrollPane scrollPane = new JScrollPane(interiorPanel);
JScrollPane scrollPane = new JScrollPane(wrapper);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(500,300));
pipelineBuilder.add(scrollPane);
JButton btnNew = new JButton("Add new panel");
btnNew.setPreferredSize(new Dimension(500, 30));
btnNew.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// if (glue!=null) {
// interiorPanel.remove(glue);
// } else {
// glue = Box.createGlue();
// }
gbc.gridy = gbc.gridy + 1;
// interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
// interiorPanel.add(glue,gbc);
// interiorPanel.validate();
interiorPanel.revalidate();
interiorPanel.repaint();
}
});
this.getContentPane().add(btnNew, BorderLayout.PAGE_START);
this.getContentPane().add(pipelineBuilder,BorderLayout.CENTER);
}
public class PipelineStep extends JPanel {
int number;
public PipelineStep (int n) {
super();
JOptionPane.showMessageDialog(interiorPanel, "adding new panel");
this.number = n;
this.setLayout(new FlowLayout());
JLabel lbl = new JLabel(new Integer(this.number).toString());
lbl.setPreferredSize(new Dimension(45,45));
lbl.setFont(lbl.getFont().deriveFont(26));
this.add(lbl);
this.setPreferredSize(new Dimension(450, 50));
this.setBorder(BorderFactory.createLineBorder(Color.green));
}
}
public static void main (String args[]) {
SSCCE1 frame = new SSCCE1();
frame.pack();
frame.setVisible(true);
}
}

In Java, is there a way to center a group of buttons with variable size(Using Swing)?

I've been trying to make a GUI like this:
However, the difficult I've run into is that I need to make the text of the buttons variable- each button should present a different option, which can vary in text length. While this itself is not difficult, I've tried countless different things but I can't get the buttons to center despite their text length. Whatever I try, I always have one of these problems:
The buttons don't center (there's space left at the left but they exceed the window at the right)
For some reason, the Question and the Goodratio change location based on the button size
I have no clue left how to do this. Does anyone have some useful intuitions on what's the best way to do this? It would be much appreciated.
EDIT: Code of the constructor function(which doesn't center correctly), which I use to set the components, as requested:
public ButtonPannel(Test test)
{
super();
op1Button = new JButton("Option 1");
op2Button = new JButton("Option 2");
op3Button = new JButton("Option 3");
questionText = new JLabel("Question");
rightAndWrongAmount = new JLabel("rightAndWrongAmount");
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{30, 331, 0};
gridBagLayout.rowHeights = new int[]{16, 0, 134, 35, 16, 0};
gridBagLayout.columnWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
setLayout(gridBagLayout);
JPanel panel = new JPanel();
FlowLayout flowLayout = (FlowLayout) panel.getLayout();
op1Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
GridBagConstraints gbc_lblQuestion = new GridBagConstraints();
gbc_lblQuestion.insets = new Insets(0, 0, 5, 0);
gbc_lblQuestion.gridx = 1;
gbc_lblQuestion.gridy = 1;
add(questionText, gbc_lblQuestion);
panel.add(op1Button);
panel.add(op2Button);
panel.add(op3Button);
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.insets = new Insets(0, 0, 5, 0);
gbc_panel.gridx = 1;
gbc_panel.gridy = 3;
add(panel, gbc_panel);
GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
gbc_lblNewLabel_1.gridx = 1;
gbc_lblNewLabel_1.gridy = 4;
add(rightAndWrongAmount, gbc_lblNewLabel_1);
op1Button.addActionListener(new InputHandler(test));
op1Button.setActionCommand("1");
op2Button.addActionListener(new InputHandler(test));
op2Button.setActionCommand("2");
op3Button.addActionListener(new InputHandler(test));
op3Button.setActionCommand("3");
}
The code is generated using WindowBuilder. The problem isn't so much in the code, but more which Layout to use etc.
Layouts are a little bit of black magic and trial and error. Very rarely will a single layout achieve exactly what you want, so you often need to resort to compound layouts (using multiple containers and layouts) to get what you want...
So, basically, this is made of a panel, with another panel holding the buttons (and another panel acting as the "pseudo" content to add space)
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
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();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Question"), gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
// This is just to act as some psudo context
add(new FillerPane(), gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
add(makeButtonPane(), gbc);
add(new JLabel("Goodratio"), gbc);
}
public JPanel makeButtonPane() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
panel.add(new JButton("Short"));
panel.add(new JButton("Long, long, long and lobng"));
panel.add(new JButton("In the middle"));
return panel;
}
}
public class FillerPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
"But I want the buttons to be the same size" I hear you ask, sure, change layouts...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
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();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Question"), gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
// This is just to act as some psudo context
add(new FillerPane(), gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
add(makeButtonPane(), gbc);
add(new JLabel("Goodratio"), gbc);
}
public JPanel makeButtonPane() {
JPanel panel = new JPanel(new GridLayout(1, 0));
panel.add(new JButton("Short"));
panel.add(new JButton("Long, long, long and lobng"));
panel.add(new JButton("In the middle"));
return panel;
}
}
public class FillerPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
You have to look at the layout and think about how each element relates to the others, in terms of what you want them to do, then find the layout managers which are going to help you achieve the end results and combine them together

GridBagLayout X and y won't go further

Okay, so I'm learning to write and use layouts by hand instead of using the GUI Builder of Netbeans. I know my question may be simple for you but not so simple for someone new to this. My problem is that even if I set gbc.gridx=10 and /or gbc.gridy=2, it won't go further to right. It looks like it's only limiting it to position 1 or 2 but won't go further. Even the gridheight = 2 or any N won't take effect. What am I doing wrong here? Please help. Thanks in advance.
package gridbaglayoutsample;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
public class GridBagLayoutSample {
JFrame myFrame = new JFrame();
JPanel myPanel_1 = new JPanel(new GridBagLayout());
JButton myButton_1 = new JButton("Button 1");
JButton myButton_2 = new JButton("Button 2");
JButton myButton_3 = new JButton("Button 3");
public GridBagLayoutSample(){
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(3,3,3,3); //insets are simple spacing for TOP LEFT BOTTOM RIGHT or PADDING
Border myLineBorder = BorderFactory.createLineBorder(Color.yellow,3);
myFrame.setLayout(new GridBagLayout());
myFrame.setPreferredSize(new Dimension(500, 500));
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setTitle("Grid Bag Layout Sample");
myFrame.setVisible(true);
myFrame.pack();
myFrame.setLocationRelativeTo(null);
myPanel_1.setBorder(myLineBorder);
gbc.gridx = 10; // set x position (STEP 1)
gbc.gridy = 0; //set y position (STEP 2)
myPanel_1.add(myButton_1,gbc); // after setting x and y, you can add (STEP 3)
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridheight = 2;
myPanel_1.add(myButton_2,gbc);
myFrame.add(myPanel_1);
}
public static void main(String[] args) {
new GridBagLayoutSample();
}
}

Can't change size of block in BorderLayout

I created simple app with Border Layout and added into it two buttons and JTable. I use JSplitPane between button2 and JTable. I would like redefine default size of block where is situated button1. How can I to solve this task?
Here is my code:
package test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
public class Sample {
public Sample() {
JFrame app = new JFrame("Sample");
app.setSize(new Dimension(800,600));
JPanel panel = new JPanel();
app.add(panel);
BorderLayout borderlayout = new BorderLayout();
panel.setLayout(borderlayout);
JButton but1 = new JButton("1");
JButton but2 = new JButton("2");
but2.setMinimumSize(new Dimension(250,0));
String[] colNames = {"Name","Number","Scores"};
Object[][] data = {
{ "Mark",11,12},
{"Tommy",23,34},
{"John",34,45}
};
JTable table = new JTable(data, colNames);
JScrollPane scrollpane = new JScrollPane(table);
JSplitPane jsplitpane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,but2,scrollpane);
panel.add(but1,BorderLayout.NORTH);
panel.add(jsplitpane,BorderLayout.CENTER);
app.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Sample();
}
});
}
}
Components in the BorderLayout.PAGE_START location have the height of their preferred sizes respected. Therefore, you can override the preferred size of JButton but1
JButton but1 = new JButton("1") {
public Dimension getPreferredSize() {
return new Dimension(100, 80);
};
};
If you are willing to use GridBagLayout for the said purpose, then I guess this Layout and do this job for you, as stated in the below pasted code example :-)
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
public class Sample {
public Sample() {
JFrame app = new JFrame("Sample");
app.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
app.setSize(new Dimension(800,600));
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
panel.setLayout(new BorderLayout(5, 5));
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridBagLayout());
JButton but1 = new JButton("1");
JButton but2 = new JButton("2");
but2.setMinimumSize(new Dimension(250,0));
String[] colNames = {"Name","Number","Scores"};
Object[][] data = {
{ "Mark",11,12},
{"Tommy",23,34},
{"John",34,45}
};
JTable table = new JTable(data, colNames);
JScrollPane scrollpane = new JScrollPane(table);
JSplitPane jsplitpane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,but2,scrollpane);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.3;
centerPanel.add(but1, gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridy = 1;
gbc.weighty = 0.7;
centerPanel.add(jsplitpane, gbc);
panel.add(centerPanel, BorderLayout.CENTER);
app.add(panel);
app.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Sample();
}
});
}
}
Here is the output of the same :

Alignment issues with BoxLayout

I am making an application for which I am using a BoxLayout. As you can see in the following picture, when the title string is short, it's perfect. But as the string gets longer, the JLabel gets more and more misaligned.
Here's some code that is related to the problem:
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
frame.add(centerPanel, BorderLayout.CENTER);
//...
JLabel l = new JLabel(/*...*/);
l.setHorizontalAlignment(SwingConstants.CENTER); //I tried removing and adding
//this but nothing changed
centerPanel.add(l);
Is there something obvious I am missing? Google isn't being helpful with this problem.
In case it's important, the country-label-progress-bar things are just JPanels with FlowLayouts.
SSCCE:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SSCCE {
public static void main(String[] args) {
final JFrame f = new JFrame("SSCCE");
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
final JLabel[] titles = new JLabel[5];
JPanel[] smallPanels = new JPanel[titles.length];
for (int i = 0; i < smallPanels.length; i ++) {
titles[i] = new JLabel(Math.random() < 0.5 ? "foo" : "bar");
p.add(titles[i]);
smallPanels[i] = new JPanel();
smallPanels[i].add(new JLabel("foobar"));
smallPanels[i].add(new JProgressBar());
p.add(smallPanels[i]);
}
f.add(p, BorderLayout.CENTER);
final JTextField tf = new JTextField("foobar");
tf.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
titles[2].setText(tf.getText());
f.repaint();
}
});
f.add(tf, BorderLayout.NORTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 600);
f.setVisible(true);
}
}
To operate the SSCCE, type something in the text field and press enter.
Here is an updated version of your SSCCE with a GridBagLayout. Not sure of how you want components to resize when labels or frame size changes but it should not be too hard to manage this.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
public class SSCCE {
public static void main(String[] args) {
final JFrame f = new JFrame("SSCCE");
JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
Insets insets = new Insets(3, 3, 3, 3);
GridBagConstraints gbc1 = new GridBagConstraints();
gbc1.gridwidth = GridBagConstraints.REMAINDER;
gbc1.anchor = GridBagConstraints.CENTER;
gbc1.insets = insets;
GridBagConstraints gbc2 = new GridBagConstraints();
gbc2.anchor = GridBagConstraints.EAST;
gbc2.insets = insets;
GridBagConstraints gbc3 = new GridBagConstraints();
gbc3.weightx = 1.0;
gbc3.fill = GridBagConstraints.HORIZONTAL;
gbc3.gridwidth = GridBagConstraints.REMAINDER;
gbc3.insets = insets;
final JLabel[] titles = new JLabel[5];
Random random = new Random();
for (int i = 0; i < titles.length; i++) {
titles[i] = new JLabel(Math.random() < 0.5 ? "foo" : "bar");
p.add(titles[i], gbc1);
p.add(new JLabel("foobar"), gbc2);
JProgressBar progress = new JProgressBar();
progress.setStringPainted(true);
progress.setString(String.valueOf(random.nextInt(100)));
p.add(progress, gbc3);
}
f.add(p, BorderLayout.CENTER);
final JTextField tf = new JTextField("foobar");
tf.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
titles[2].setText(tf.getText());
f.repaint();
}
});
f.add(tf, BorderLayout.NORTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
BoxLayout accepting Min, Max and PreferredSize, childs could be resizable from Min to MaxSize
FlowLayout accepting only PreferredSize, rest (Min, MaxSize) is ignored by this LayoutManager, childs aren't resizable
these XxxSize are calculated from PreferredSize came from childs placed into container (JPanel in this case)
(your question) for better help sooner post an SSCCE, short, runnable, compilable, just about your issue

Categories

Resources