I would like to create a layout: 2 rows, 1 column. 1st row should occupy 70% height of the window and 2nd row 30% of the window. I achieve this by using weighty attribute of GridBagConstraints.
However I have problem with the width of my component, because when I resize application window the component remain in the center, its width is constant and I get a white spaces in the left and right of the component (even if I set fill to BOTH). This problem does not occur when I change the height of the window (components resize very well and fill full height of the window).
Below my constraints:
firstConstraints.gridx = 0;
firstConstraints.gridy = 0;
firstConstraints.weighty = 0.7;
firstConstraints.fill = GridBagConstraints.BOTH;
secondConstraints.gridx = 0;
secondConstraints.gridy = 1;
secondConstraints.weighty = 0.3;
secondConstraints.fill = GridBagConstraints.BOTH;
I think you also need:
gbc.weightx = 1.0;
See the secton from the Swing tutorial on How to Use a GrigBagLayout that talks about the weightx, weighty constraints.
simple example
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class BorderPanels extends JFrame {
private static final long serialVersionUID = 1L;
public BorderPanels() {
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
gbc.gridx = gbc.gridy = 0;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 70;
getContentPane().add(panel1, gbc);
JPanel panel2 = new JPanel();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
gbc.gridy = 1;
gbc.weightx = 30;
gbc.weighty = 30;
gbc.insets = new Insets(2, 2, 2, 2);
getContentPane().add(panel2, gbc);
pack();
}
public static void main(String[] args) {
new BorderPanels().setVisible(true);
}
}
Related
I was wondering how to center my components, I found the gridBagLayout but I couldn't find a way to have it bigger than it is : my buttons are too small.
Part of my code :
private void addMainButtons() {
JPanel container = new JPanel() {
private static final long serialVersionUID = -424395301619105440L;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension dim = this.getSize();
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date date = new Date();
g.setFont(new Font("TimesRoman", Font.PLAIN, 20));
g.setColor(Color.BLACK);
String s = format.format(date);
g.drawString(s, (int) ((dim.getWidth() - s.length() - 80) / 2), 20);
}
};
container.setBackground(new Color(109, 69, 60));
JButton productsButton = new JButton("Produits");
productsButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cl.show(frame, pages[1]);
}
});
productsButton.setAlignmentY(Component.CENTER_ALIGNMENT);
productsButton.setAlignmentX(Component.CENTER_ALIGNMENT);
// Creating grid
container.setPreferredSize(new Dimension(400, 600));
container.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
container.add(productsButton, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1;
container.add(new JButton("Entrée"), gbc);
gbc.gridx = 1;
container.add(new JButton("Sortie"), gbc);
mainPage.setLayout(new BorderLayout());
mainPage.add(container, BorderLayout.CENTER);
// End of main page
}
GridBagLayout is really difficult to use, is there another way to center components ? I could use NestedLayouts but I don't know how.
You can use weightx and/or weighty to effect the amount of space the components will occupy, for example, if I do
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.weightx = 1;
gbc.weighty = 1;
container.add(productsButton, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1;
container.add(new JButton("Entrée"), gbc);
gbc.gridx = 1;
container.add(new JButton("Sortie"), gbc);
I can generate this...
You could use two containers, one holding a JLabel which shows the date and one which contains the buttons, but I doubt that's what you're really after.
You can use ipadx and ipady which adds the amount to the components preferred size
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.ipadx = 40;
gbc.ipady = 40;
container.add(productsButton, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1;
container.add(new JButton("Entrée"), gbc);
gbc.gridx = 1;
container.add(new JButton("Sortie"), gbc);
which, when included with your existing constraints, allows you to "grow" the buttons a bit.
Try below code for increasing size of button while adding every components to gridbagconstraints. Change the value of weightx/weighty as you want.
gbc.weightx = 1.0;
gbc.weighty = 1.0;
To give more spaces between components, use below code while adding every components to gridbagconstraints.
gbc.insets = new Insets(2, 2, 2, 2);
According to my knowledge, you used correct way to center components. It can also be done by other layout but it may be little bit difficult.
I want to create an application with buttons arrayed into invisible table. The buttons should fill all the available space inside the imaginary cells even when I´ll resize the frame. I´m using Swing, GridBagLayout. I've read some articles and the solution was to add .weightx=1 and .weighty=1. Weightx works perfect and it fill the gaps but weighty doesn't. Buttons don´t extend into height of cell. Is there a problem with my code or is there something to add that solve my problem? Or should I use absolutely another layout?
public class NewClass {
public void NewClass(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
GridBagLayout layout = new GridBagLayout();
panel.setLayout(layout);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
JButton B11 = new JButton("11");
panel.add(B11,gbc);
gbc.gridx = 1;
gbc.gridy = 0;
JButton B12 = new JButton("12");
panel.add(B12,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
JButton B21 = new JButton("21");
panel.add(B21,gbc);
gbc.gridx = 1;
gbc.gridy = 1;
JButton B22 = new JButton("22");
panel.add(B22,gbc);
frame.pack();
frame.setSize(800,400);
frame.setVisible(true);
}}
You're using the wrong GridBagConstraints#fill field value, since the value you're using is telling the layout manager to fill the buttons horizontally only.
You need to change
gbc.fill = GridBagConstraints.HORIZONTAL;
to
// gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.fill = GridBagConstraints.BOTH;
if you want the buttons to fill both directions, both horizontally and vertically.
I have a TabbedPane inside of which there are Panels.
I am dealing now with the first panel.
Inside this panel there should be another small panel on the left(I just placed a textfield instead for reference) a textarea in the center and below it a row of buttons. But the buttons are placed far too low below from the textarea. Besides, if I resize the frame, the textarea just goes away, vanishes. The textfield is set ok, top left, the textarea more or less yes in the center, but it should not go away when resizing (it would make a weird effect for the user).
I have tried all variants south, west, whatever, no changes or it goes up too far anyways.
I have read somewhat similar questions but I dont see how their answers solve my case.
So, here is the code:
super("Proyecto");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(1200, 800);
/* 1. CREATE PANEL*/
/*MAIN PANEL BOOK READER*/
JPanel panelbookreader = new JPanel();
/*CREATE TEXTAREA*/
JTextArea areatextobookreader = new JTextArea(20, 80);
/* 2. ADD THAT COMPONENT TO ITS PARENT*/
panelbookreader.add(areatextobookreader);
/* 3. SET A LAYOUT FOR THE PANEL THAT WILL ORGANIZE COMPONENTS INSIDE*/
panelbookreader.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JTextField hold = new JTextField(20);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
panelbookreader.add(hold, gbc);
//TEXT AREA
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 0;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
panelbookreader.add(areatextobookreader, gbc);
//BUTTONS
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.SOUTH;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
panelbookreader.add(openbook, gbc);
/*ADD THE PARENT TO ITS PARENT OR TO GRANPARENT OF COMPONENT*/
JTabbedPane tabulado = new JTabbedPane();
tabulado.addTab("BOOK READER",panelbookreader);
Your weightx for JTextArea is 1.0 which is fine.
But when you specify weighty also as 1.0, then there is no space for JButton. Make some changes in weighty of textarea and also specify weighty for jbutton.
Here is a tough one for you guys :)
Basically I have a GridBagLayout with 2 columns : a list wrapped in a scrollpane in each one. The scrollpanes are stretched in BOTH direction.
If I progressively reduce the height of this panel (by dragging the window's edge), I see "random" resizing happening on the scrollpanes:
second one's width gets reduced when first's Hscroll bar appears
then, second one's width gets shrinked again for no reason...
If i don't wrap my components, don't get this behavior.
And if you replace the right hand list with a tree, it will behaves differently:
shrinking the window's height bellow 380-ich px, the tree gets resized...
If i don't wrap my components, the tree gets resized anyway if you keep resizing the window !
Do you guys have any idea what's going on ???
PS: the actual layout i am trying to build is more complex than this example. In the mean time i use SpringLayout to do what i want but it requires to much (not so beautiful) things to setup
protected static ListModel newListModel(int n) {
DefaultListModel lm = new DefaultListModel();
for (int i = 0; i < n; ++i)
lm.addElement("AAA");
return lm;
}
protected static JComponent createContentPane() {
JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridy = 0;
gbc.gridx = 0;
pane.add(new JScrollPane(new JList(newListModel(12))), gbc);
++gbc.gridx;
pane.add(new JScrollPane(new JList(newListModel(4))), gbc);
return pane;
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.getContentPane().add(createContentPane());
f.setSize(800, 400);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
I have an application with several ScrollPanes in a GridBagLayout, and they also exhibit sudden resizes when I resize the window. It seems that a jump occurs when the actual size of the ScrollPane steps over its "preferred size". I have found a workaround: set the preferred size to 1x1 pixels. If the component has positive weight and stretches BOTH, it will still occupy the whole cell, but will not jump. If you need several cells to resize in different proportions, you can set preferred size of another one to, say, 2x1 pixels.
this is basic principles of GridBagLayout, you forgot for define anchor, then you can be able to fix placed JComponent to the rellative Point, and I think that GridBagLayout complicated your GUI, this LayoutManager is better use for placing lots of JComponents to the one container,(without using nested layout)
for example
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class BorderPanels extends JFrame {
private static final long serialVersionUID = 1L;
public BorderPanels() {
setLayout(new GridBagLayout());// set LayoutManager
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
gbc.gridx = gbc.gridy = 0;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 20;
add(panel1, gbc); // add compoenet to the COntentPane
JPanel panel2 = new JPanel();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "60pct"));
gbc.gridy = 1;
gbc.weightx = gbc.weighty = 60;
//gbc.insets = new Insets(2, 2, 2, 2);
add(panel2, gbc); // add component to the COntentPane
JPanel panel3 = new JPanel();
panel3.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
gbc.gridy = 2;
gbc.weightx = gbc.weighty = 20;
gbc.insets = new Insets(2, 2, 2, 2);
add(panel3, gbc);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // important
pack();
setVisible(true); // important
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() { // important
public void run() {
BorderPanels borderPanels = new BorderPanels();
}
});
}
}
to avoiding against to complicating simple things
use GridLayout (all JComponents have got same Dimmension on the screen)
use BoxLayout or BorderLayout
I have a panel in which i have specified with a grid bag layout. I basically have 1 column and 4 rows. The labels are aligned to the center by default. How do i align them to the left?
private void addLabel(String name, int gridx, int gridy, int anchor ){
gbc.gridx=gridx;
gbc.gridy=gridy;
JLabel label=new JLabel(name);
gbc.fill=GridBagConstraints.HORIZONTAL;
gbag.setConstraints(label, gbc);
panel1.add(label);
The caller lines are:
gbc=new GridBagConstraints();
gbag=new GridBagLayout();
panlel1.setLayout(gbag);
addLabel(" Exemption type", 0, 0,anchor );
try
JLabel myLabel = new JLabel("Fubar", SwingConstants.LEFT);
Or you could do the same on an already created JLabel by calling myLabel.setHorizontalAlignment(SwingConstants.LEFT);
edit: for example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.*;
public class GridBagExample {
private static void createAndShowUI() {
String[] data = {"one", "two", "three", "four"};
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0; // **** comment this line out to see effect ****
gbc.weighty = 1.0; // **** comment this line out to see effect ****
for (int i = 0; i < data.length; i++) {
JLabel label = new JLabel(data[i]);
gbc.gridy = i;
panel.add(label, gbc);
}
JFrame frame = new JFrame("GridBagExample");
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Here is how I solved this.
The important part is
gbc.anchor = GridBagConstraints.WEST;
The above is called right after you specify the layout cell you want and right before you add the component to the panel.
GridBagConstraints anchor
This field is used when the component is smaller than its display
area. It determines where, within the display area, to place the
component. ...
Below is basically how I implemented it.
public class ControlPanel extends JPanel{...
ControlPanel(){
this.setLayout(new GridBagLayout());
//create components
...
GridBagConstraints gbc = new GridBagConstraints();
//space components out a little
gbc.insets = new Insets(5,5,5,5);
gbc.gridx = 0;
gbc.gridy = 0;
this.add(button_btn,gbc);
gbc.gridx = 1;
gbc.gridy = 0;
this.add(spinner1_pnl,gbc);
gbc.gridx = 2;
gbc.gridy = 0;
this.add(spinner2_pnl,gbc);
gbc.gridx = 3;
gbc.gridy = 0;
this.add(checkbox1_chk,gbc);
gbc.gridx = 4;
gbc.gridy = 0;
this.add(checkbox2_chk,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 3; //span 3 columns
gbc.anchor = GridBagConstraints.WEST;
this.add(results_lbl,gbc);
}
}
In this case I put a label below some other components, but most importantly that label is left (west) aligned within its cell.