Grid Bag Layout doesnt recognize my commands? - java

Im making an application that uses a lot of constructors, and I understood that you cant use the Drag and Drop tool of netbeans for making a constructor, and i thought it was good idea to learn how to code fully organized windows, anyways I read a DEITEL Java book that uses a method for adding objects to the container, here it is:
private void addobject(Component componente, int column, int row, int width
int height){
//C will be the GridBagConstraints
//And I made a new GridBagLayout called "v"
//My Panel or container is called objcontainer and the LayoutManager is v
c.gridx = column;
c.gridy = row;
c.gridwidth = width;
c.gridheight = height;
v.setConstraints(componente, c);
objcontainer.add(componente);
}
The method is declared in the same class in where the constructor is, it worked separating only by one gridy. But when I put it 2 or more away that the last object it just stays like if I put 1.
I dont know if thats how it works, also the anchors dont work perfectly, besides the LINE START one, the Center ones are failing.
Here is the code, anyways thanks:
package Windows;
import java.awt.*;
import javax.swing.*;
public class agregaringreso extends JDialog{
private int ingreso;
private String nombreingreso;
private String Frecuencia [] = {"Solo una vez", "Cada semana","Cada 2 semanas", "Cada 3 semanas", "Cada mes,"};
Container contenedor;
JPanel objcontainer;
GridBagLayout esquema;
GridBagConstraints c;
JButton aceptar;
JLabel title;
JLabel ingreso2;
JLabel nombreingreso2;
JLabel frecuencia2;
JTextField ingreso3;
JTextField nombreingreso3;
JComboBox frecuencia3;
private void addobjeto(Component componente, int columna, int fila, int ancho, int alto){
c.gridx = columna;
c.gridy = fila;
c.gridwidth = ancho;
c.gridheight = alto;
esquema.setConstraints(componente, c);
objcontainer.add(componente);
}
public agregaringreso(){
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Agregar Nuevo Ingreso - EkPek");
pack();
setResizable(false);
setSize(500, 200);
setLocationRelativeTo(null);
//FASE DE INICIALIZACION
contenedor = getContentPane();
objcontainer = new JPanel();
esquema = new GridBagLayout();
c = new GridBagConstraints();
aceptar = new JButton("Aceptar");
title = new JLabel("Agregar Nuevo Ingreso");
ingreso2 = new JLabel("Monto del Ingreso: ");
nombreingreso2 = new JLabel("Nombre del Ingreso: ");
frecuencia2 = new JLabel("Frecuencia con la cual recibe el ingreso: ");
ingreso3 = new JTextField("Escriba aqui el monto");
nombreingreso3 = new JTextField("Escriba aqui el nombre");
frecuencia3 = new JComboBox(Frecuencia);
//FASE DE ACOMODO
c.anchor = GridBagConstraints.CENTER;
addobjeto(title, 0, 0, 1, 1);
c.anchor = GridBagConstraints.LINE_START;
addobjeto(nombreingreso2 , 0, 4, 1, 1);
addobjeto(nombreingreso3, 1, 4, 1, 1);
addobjeto(ingreso2, 0, 5, 1, 1);
addobjeto(ingreso3, 1, 5, 1, 1 );
addobjeto(frecuencia2, 0 , 6, 1, 1);
addobjeto(frecuencia3, 1, 6, 1, 1);
c.anchor = GridBagConstraints.CENTER;
addobjeto(aceptar,0 ,7 ,1, 1);
contenedor.add(objcontainer);
objcontainer.setLayout(esquema);
setVisible(true);
}
}

The order in which you do things is very important. It pointless doing something like...
objcontainer = new JPanel();
esquema = new GridBagLayout();
// Add a bunch of stuff
objcontainer.setLayout(esquema);
You've basically added components to a container (which is using a FlowLayout) and then changed the layout manager. The constraints won't carry across, they are typically incompatiable between layouts (what's a FlowLayout going to do with GridBagConstraints anyway)
Instead, set the layout first
objcontainer = new JPanel();
esquema = new GridBagLayout();
objcontainer.setLayout(esquema);
// Add components.
This also holds true for when you establish a window...
public agregaringreso(){
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Agregar Nuevo Ingreso - EkPek");
pack();
setResizable(false);
setSize(500, 200);
setLocationRelativeTo(null);
It's all kind of pointless, as you've not actually added anything to the window, so pack can't actually do it's job (it's got nothing to pack)
Instead, build the UI first, the "set up" the window properties...
public agregaringreso(){
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Agregar Nuevo Ingreso - EkPek");
//FASE DE INICIALIZACION
contenedor = getContentPane();
contenedor.setBackground(Color.RED);
objcontainer = new JPanel();
esquema = new GridBagLayout();
objcontainer.setLayout(esquema);
c = new GridBagConstraints();
// Add components
setResizable(false);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

it worked separating only by one gridy. But when I put it 2 or more away that the last object it just stays like if I put 1.
If you mean that jumping the value of gridy doesn't do anything than you're right, it's intended. The grid only consists of rows and columns which have components in them.
Example: if you have 2 components, the first at (0,0) and the second at (0,4), then the gridy values 1 through 3 are not counted. The result is that the second component is actually at (0,1). Same goes for gridx.
also the anchors dont work perfectly, besides the LINE START one, the Center ones are failing.
In your example the CENTER anchor value is functioning as intended. If the component is smaller than its available space (and it was not instructed to fill that space with fill), it will be aligned to the center of the space.
What you probably want it for the component to be in the center of the whole grid, and not in the center of its available space. To do this, you must set it so that the component spans the grid's width (or height) by setting its gridwidth appropriately.
Picture comparison
#MadProgrammer's answer already explained how to fix your setup (I will mention it below in the notes). You're supposed to get the top picture after those corrections. The red lines separate rows and the blue lines separate columns - this is your grid.
You see that the components in the first and last rows are centered in column 0 because this is their available space. In the bottom picture, they are centered in both columns since I instructed them to span 2 columns.
I also noted a space discrepancy in the top picture with a yellow rectangle. This happens because the components are not filling all their available space. While it's your choice, it is customary in such layout to do as shown in the bottom picture.
Code comparison
c.anchor = GridBagConstraints.CENTER; // Redundant - default
addobjeto(title, 0, 0, 2, 1);
c.anchor = GridBagConstraints.LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
addobjeto(nombreingreso2, 0, 1, 1, 1);
addobjeto(nombreingreso3, 1, 1, 1, 1);
addobjeto(ingreso2, 0, 2, 1, 1);
addobjeto(ingreso3, 1, 2, 1, 1);
addobjeto(frecuencia2, 0, 3, 1, 1);
addobjeto(frecuencia3, 1, 3, 1, 1);
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.NONE;
addobjeto(aceptar, 0, 4, 2, 1);
Set the gridwidth of title and aceptar to 2 (GridBagConstraints.REMAINDER will also work) to allow them to span 2 columns.
For the rest of the components, set c.fill = GridBagConstraints.HORIZONTAL; to allow them to align nicely with themselves (yellow rectangle). Remember to reset it c.fill = GridBagConstraints.NONE; for aceptar if you don't want the button to strech.
Specifying c.anchor = GridBagConstraints.CENTER; is redundant for the first component as it is the default, but it can make the code clearer.
Notes:
You don't need your JLabels to be fields as you probably don't need to hold a reference to them. Local variables will do just as well and will decrease the memory usage.
Class names should start with an uppercase (Agregaringreso).
As for my "setup" (as MadProgrammer explained): before adding the components I have
esquema = new GridBagLayout();
objcontainer = new JPanel(esquema);
c = new GridBagConstraints();
and at the end I have
getContentPane().add(objcontainer);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Agregar Nuevo Ingreso - EkPek");
pack();
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
(You don't need to hold a reference to the content pane.)

Related

How to set JButton size with GridBagLayout

I want to set the size of my JButtons that are at the center of my screen to become larger but I can't seem to find how to do that using GridBagLayouts.
Here is how it looks like :
Here is my code :
// Client
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
c.gridy = 5;
c.gridx = 5;
c.gridwidth = 1;
c.gridheight = 1;
c.insets = new Insets(10, 1, 1, 10);
p.add(b[0], c);
// Server
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
c.gridy = 10;
c.gridx = 5;
c.gridwidth = 1;
c.gridheight = 1;
c.insets = new Insets(10, 1, 1, 10);
p.add(b[1], c);
I want the buttons to take up a larger portion of the empty space around them.
More information was added: Buttons have 50% of the width and [about] 20% of the height of parent [together 50% height including the space in between]. (Slightly rewritten to match the suggestion.)
Solution
Combination of simple Layouts Layouts. Although if you do it like this you will have 3 columns or 3 rows which can't be joined, the rest can easily be changed later:
// row variation
JPanel parent = new JPanel();
parent.setLayout(new GridLayout(3, 1));
parent.add(new JPanel()); // placeholder for 1st row
JPanel row = new JPanel(); // 2nd row
row.setLayout(new GridLayout(1, 3)); // create 3 cells of equal size
row.add(new JPanel()); // 2nd row, 1st cell placeholder
// now you have a 33% x 33% (oops) rectangle in the middle
JPanel controls = new JPanel();
controls.setLayout(new GridLayout(2, 1, 10, 10));
controls.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10);
controls.add(new JButton("Client"));
controls.add(new JButton("Server"));
row.add(controls); // add 2nd row, 2nd cell
row.add(new JPanel()); // 2nd row, 3rd cell placeholder
parent.add(row); // add 2nd row
parent.add(new JPanel()); // placeholder for 3rd row
Easy, but you won't be able to join the cells later:
JPanel parent = new JPanel();
parent.setLayout(newGridLayout(9, 9));
Bottom line: combine different layout managers, put your 2 buttons inside a panel and put some placeholders inside, then it should also work fine with GridBagLayout. That said, I would try to stay flexible by writing reusable components which can easily be combined with any layout manager. Then you don't have to use placeholders superfluous code in order to display the components correctly.
Old Answer
Alternative Solution: Use BoxLayout
BoxLayout is more intuitive and easier to understand when looking at code (of course this is only an opinion).
Decide how your window is structered (is it more like big horizontal components on top of each other PAGE_AXIS or big vertical components next to each other LINE_AXIS) and use this as the outer BoxLayout:
JPanel content = new JPanel(); // or frame
content.setLayout(new BoxLayout(content, BoxLayout.LINE_AXIS));
Add the components along the axis, where you have more than one component along the other axis use a 2nd BoxLayout. You can space components by creating rigid areas (empty rectangles always having the same size) or by adding glue (expanding like gum together with the components).
content.add(BoxLayout.createHorizntalGlue());
JPanel col = new JPanel();
col.setLayout(new BoxLayout(col, BoxLayout.PAGE_AXIS));
JButton clientBtn = new JButton("Client");
JButton serverBtn = new JButton("Server");
col.add(BoxLayout.createVerticalGlue());
col.add(clientBtn);
col.add(BoxLayout.createRigidArea(new Dimension(1, 10)));
col.add(serverBtn);
col.add(BoxLayout.createVerticalGlue());
content.add(col);
content.add(BoxLayout.createHorizontalGlue());
I can't imagine what do you want, but if you want your button to fill around, you can add
c.weightx = ...; //Specifies how to distribute extra horizontal space.
or c.weighty = ...; //Specifies how to distribute extra vertical space.
button.setMargin( new Insets(50, 50, 50, 50) );
This will add extra space to the button and allow the layout managers to do their job based on the preferred size of the button.

JInternal Frame Over JPanel

I need some help in JInternalFrame within JPanel's Area.I have a JFrame which contains
JPanel added to its ContentPane.JFrame Contains Menu when i click one of its Menu item i
need JInternal Frame to be added on top of the contentpane.The Code i have given so far,
JDesktopPane desktop = new JDesktopPane();
desktop.setLayout(new BorderLayout());
JPanel topPanel = new JPanel();
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] { 0, 0, 0, 0 };
gbl_contentPane.rowHeights = new int[] { 0, 0, 0, 0 };
gbl_contentPane.columnWeights = new double[] { 1.0, 6.0, 1.0,
Double.MIN_VALUE };
gbl_contentPane.rowWeights = new double[] { 0.0, 8.0, 0.0,
Double.MIN_VALUE };
topPanel.setLayout(gbl_contentPane);
JPanel left = new JPanel();
GridBagConstraints gbc_left = new GridBagConstraints();
gbc_left.insets = new Insets(0, 0, 5, 5);
gbc_left.fill = GridBagConstraints.BOTH;
gbc_left.gridx = 0;
gbc_left.gridy = 1;
topPanel.add(left, gbc_left);
JPanel middle = new JPanel();
GridBagLayout gbl_middle = new GridBagLayout();
gbl_middle.columnWeights = new double[] { 1.0 };
middle.setLayout(gbl_middle);
GridBagConstraints gbc_middle = new GridBagConstraints();
gbc_middle.insets = new Insets(0, 0, 5, 5);
gbc_middle.fill = GridBagConstraints.BOTH;
gbc_middle.gridx = 1;
gbc_middle.gridy = 1;
topPanel.add(middle, gbc_middle);
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = gbc.weighty = 30;
middle.add(panel1, gbc);
panel1.setLayout(new MigLayout("", "[944.00,grow][353.00]",
"[6.00][128.00,grow][]"));
/*lblHeader = new JLabel(
"<html>Indira Institute of Technology<br>Tatabad<br>Karpagam Complex Stop<br>Coimbatre</html>");
lblHeader.setIcon(new ImageIcon(
"C:\\Users\\Prakash\\Desktop\\images.jpg"));
panel1.add(lblHeader, "cell 0 1 2 1,alignx center,aligny center");*/
JPanel panel2 = new JPanel();
gbc = new GridBagConstraints();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
gbc.gridy = 1;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 70;
gbc.insets = new Insets(2, 2, 2, 2);
middle.add(panel2, gbc);
panel2.setLayout(new MigLayout(
"",
"[30px][69.00px][144.00][68.00][][159.00px][59.00px][65px][28.00][]",
"[20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][30.00][48.00:n,grow 50,shrink 50]"));
getContentPane.add(topPanel);
I have never used the DesktopPane in this(I don't know how to make use of this in this situation) And The Screen So far is as follows,
Now I need the JInternalFrame to be added for the Previous Screen as Follows,
I am aware that i can only be able to add a JInternalFrame to the DesktopPane.But i
Already Filled my ContentPane with JPanel to show its content.How can i achieve Jinternal
Frame to be added in this JFrame.Kindly give your valuable suggestions.
Not really the right direction. You original panel is under the control of layout manager, this means that when you add the JInternalFrame to it, the layout manager wants to try and layout it out.
Generally speaking, a JInternalFrame wants to reside in a container which is unmanaged, allowing it to be positioned and sized independently of the content.
A possible solution might be to take advantage of the glass pane for the JInternalFrame instead, for more details see How to Use Root Panes
Another solution might be to use a JLayeredPane. Basically, you would start by setting the layout manager of the JLayeredPane to something link BorderLayout add the first panel to it and then add a second, transparent pane, with no layout, above it. You would add the JInternalFrames to this second panel.
See How to Use Layered Panes for more details
The question that jumps out at me though is...why? Why wouldn't you just use some kind of dialog instead? See How to Make Dialogs for more details
What is it what you really want?
You wrote you already have your content pane added to your frame. JDesktopPane has to have its own space reserved. If you don't have or you don't want to reserve space for the internal frames in your main frame, then maybe you don't even want it to be part of the main frame. In this case you might want to use child JDialogs instead of JInternalFrames.
So either add your JDesktopPane to your main frame (having its space reserved) or use child JDialogs which can be modal or not and can overlap any part of the main frame. JInternalFrames are only visible in the area of the JDesktopPane while child JDialogs can "float" over your main frame.
Check out this Oracle documentation: How to Use Internal Frames
And How to Make Dialogs.

Java Swing GridBagLayout Component Positioning

I am using Swing's GridBagLayout for the fist time and I have so far only added two components to a container, although I intend to add more below vertically. So far, the first component (a JLabel) is positioned correctly at PAGE_START, and I have remembered to set weight attributes for the components' corresponding GridBagConstraints. The second component (a JTextField) however is not positioning as I intended and it being centered in the container rather than moving up underneath the JLabel. I have attempted to use multiple anchor constants including FIRST_LINE_START, PAGE_START, NORTH & NORTHWEST but so far nothing is working.
And so, once again I call for the gifted coders of stackoverflow for help. Below is a snippet of the code and below that is an image of the problem graphically.
// Instantiate components and configure their corresponding GridBagConstraints attributes
// refPlusType properties
refPlusType = new JLabel("<html><h3>"+"Reference"+" - "+"Job Type"+" </h3><hr /></html>");
refPlusTypeGC = new GridBagConstraints();
refPlusTypeGC.gridx = 0; // Grid position
refPlusTypeGC.gridy = 0;
refPlusTypeGC.gridwidth = 2; // Number of colums occupied by component
refPlusTypeGC.insets = new Insets(5, 10, 5, 10); // Specifies margin
refPlusTypeGC.weightx = 0.1; // Required for anchor to work.
refPlusTypeGC.weighty = 0.1; // Required for anchor to work.
refPlusTypeGC.anchor = GridBagConstraints.PAGE_START; // Position in container
// addressLine1 properties
addressLine1 = new JTextField();
addressLine1GC = new GridBagConstraints();
addressLine1GC.gridx = 0;
addressLine1GC.gridy = 1;
addressLine1GC.gridwidth = 2;
addressLine1GC.insets = new Insets(0, 10, 0, 10);
addressLine1GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
addressLine1GC.weightx = 0.1;
addressLine1GC.weighty = 0.1;
addressLine1GC.anchor = GridBagConstraints.FIRST_LINE_START;
// Add components to this HALLogisticsDetailsPanel
this.add(refPlusType, refPlusTypeGC);
this.add(addressLine1, addressLine1GC);
Image below;
Thank you all for any help you can offer.
Try increasing the weighty for addressLine1 to a much larger value. I did a quick test setting it to 1000:
addressLine1GC.weighty = 1000.0;
and that pushed the addressLine1 field up under the label with the whitespace below.
anchor = NORTH works like a charm:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestJPanels {
private JLabel refPlusType;
private JTextField addressLine1;
protected void initUI() {
final JFrame frame = new JFrame(TestJPanels.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
// Instantiate components and configure their corresponding GridBagConstraints attributes
// refPlusType properties
refPlusType = new JLabel("<html><h3>" + "Reference" + " - " + "Job Type" + " </h3><hr /></html>");
GridBagConstraints refPlusTypeGC = new GridBagConstraints();
refPlusTypeGC.gridwidth = GridBagConstraints.REMAINDER; // Number of colums occupied by component
refPlusTypeGC.insets = new Insets(5, 10, 5, 10); // Specifies margin
refPlusTypeGC.weightx = 1; // Required for anchor to work.
refPlusTypeGC.anchor = GridBagConstraints.PAGE_START; // Position in container
// addressLine1 properties
addressLine1 = new JTextField(20);
GridBagConstraints addressLine1GC = new GridBagConstraints();
addressLine1GC.insets = new Insets(0, 10, 0, 10);
addressLine1GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
addressLine1GC.weightx = 1;
addressLine1GC.weighty = 1;
addressLine1GC.anchor = GridBagConstraints.NORTH;
// Add components to this HALLogisticsDetailsPanel
panel.add(refPlusType, refPlusTypeGC);
panel.add(addressLine1, addressLine1GC);
frame.add(panel);
frame.setSize(600, 600);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestJPanels().initUI();
}
});
}
}
The best 'tutorial' for GridBagLayout that I have seen was created by Scott Stanchfield. You can find a link to the PowerPoint presentation he gave at JavaOne 2001 here
There used to be an article online with the same information, but it appears to have been swallowed up by Oracle.
Please read all the warnings about why GBL is not ideal. If you are determined to use it, Scott gives a great visual lesson on how to determine all the constraints by creating a simple sketch of your GUI.
Jim S.
Okay, I got it. I don't like accepting my own answers but here we go. At the end of the day I am trying to get the whole lot to bunch together properly at the top of the container. Adding weighty attributes to all the components individually means that the remaining space in the container is distributed between all of them (relative to their weighty attribute) therefore spacing them out.
The answer seems to be that by adding a weighty attribute to the lowest component in the GridBagLayout, the rest of the remaining space is allocated to below the lowest component and therefore pushing all components to the top. By default is seems that when remaining space is allocated to a component based on it's weight, it is allocated below it (at least on the y axis).
Here is the new code with three components to help demonstrate;
// Instantiate components and configure their corresponding GridBagConstraints attributes
// refPlusType properties
refPlusType = new JLabel("<html><h3>"+"Reference"+" - "+"Job Type"+" </h3><hr /></html>");
refPlusTypeGC = new GridBagConstraints();
refPlusTypeGC.gridx = 0; // Grid position
refPlusTypeGC.gridy = 0;
refPlusTypeGC.gridwidth = 2; // Number of colums occupied by component
refPlusTypeGC.insets = new Insets(5, 10, 5, 10); // Specifies margin
// addressLine1 properties
addressLine1 = new JTextField();
addressLine1GC = new GridBagConstraints();
addressLine1GC.gridx = 0;
addressLine1GC.gridy = 1;
addressLine1GC.gridwidth = 2;
addressLine1GC.insets = new Insets(0, 10, 0, 10);
addressLine1GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
// addressLine2 properties
addressLine2 = new JTextField();
addressLine2GC = new GridBagConstraints();
addressLine2GC.gridx = 0;
addressLine2GC.gridy = 2;
addressLine2GC.gridwidth = 2;
addressLine2GC.insets = new Insets(0, 10, 0, 10);
addressLine2GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
addressLine2GC.weighty = 1; // Required for anchor to work.
addressLine2GC.anchor = GridBagConstraints.NORTH; // Position in container
// Add components to this HALLogisticsDetailsPanel
this.add(refPlusType, refPlusTypeGC);
this.add(addressLine1, addressLine1GC);
this.add(addressLine2, addressLine2GC);

Java GridBagLayout + Absolute Layout

I am trying to make a 3 column layout, in each column i want to be able to absolute position labels and textboxes.
Problem is that my label (jLabel2) never even gets displayed..
Here is my code:
/**
* Top JPanel (Top)
*/
JPanel pnlTop = new JPanel();
pnlTop.setBackground(new java.awt.Color(223, 223, 217));
pnlTop.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new java.awt.Color(173, 173, 166)));
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 5; // five rows
c.gridheight = 1; // one column
c.fill = GridBagConstraints.BOTH;
//c.weighty = 0.04;
add(pnlTop, c);
/**
* Top JPanel Content (Here is where i want to put absolute content)
*/
JPanel pnlTopContent = new JPanel();
pnlTopContent.setLayout(null);
jLabel2.setFont(new java.awt.Font("Lucida Grande", 1, 16)); // NOI18N
jLabel2.setText("Hello");
jLabel2.setLocation(150, 50);
pnlTopContent.add(jLabel2);
pnlTop.add(pnlTopContent);
Any ideas what i am doing wrong?
Then its showing but not in the right place
What does "right place" mean to you? Why are you even adding you label to a second panel? Why not just add the label directly to the pnlTopContent?
GridBagLayout has a constraint that allows you to position the component right/left/center of the column. Read the section from the Swing tutorial on How to Use GridBagLayout. You might want to start with the anchor constraint.
Use layout manager for pnlTopContent. Which one is right depends on what you want. Even the default FlowLayout might work. If you want to center the label, you can for example use FlowLayout with center alignment:
pnlTopContent.setLayout(new FlowLayout(FlowLayout.CENTER));

How to use GridBagConstraints to create the layout?

I want to layout my JPane like so:
-------
| |
| |
| |
-------
| |
-------
This way, the top section is bigger/taller than the bottom section (the top section consists of another JPanel and uses the Graphics object to display an image, while the bottom section also consists of another JPanel but uses the Graphics object to draw some lines and text).
I've heard that the best way to do this was using the GridBagLayout and GridBagConstraints.
I'm trying to figure out the appropriate properties for the GridBagConstraints, and I'm having some difficulties. This is what I have so far...
For the top part, I have:
gridx = 0
gridy = 0
weighty = 1.0; // expand downwards, because the bottom should never expand in the Y direction
fill = GridBagConstraints.BOTH
For the bottom part, I have:
gridx = 0
gridy = 1
fill = GridBagConstraints.HORIZONTAL
anchor = GridBagConstraints.PAGE_END
Unfortunately, all the ends up happening is a large gray rectangle appears (I have a white background for the application) - no images load, no lines/text appear.
What should I do? What should I adjust?
I've read a few tutorials, but it just seems really confusing, I got it working in my first application, but now when I try to do this it just doesn't seem to work for me.
In general, for gridbag layout
if you want a component scale, you must give its scale direction a weight, and any sizes (width/height) you set for that direction will be ignored by the layout manager.
If you don't want a component scale, the component must have its size defined (if you want, you can dig into this topic in documents of java). In your case of the bottom panel, you need to give its, at least, a preferred height.
This can work as your expectation
pnlTop.setBackground(Color.WHITE);
pnlBottom.setBackground(Color.BLUE);
// Because you don't want the bottom panel scale, you need to give it a height.
// Because you want the bottom panel scale x, you can give it any width as the
// layout manager will ignore it.
pnlBottom.setPreferredSize(new Dimension(1, 20));
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints cst = new GridBagConstraints();
cst.fill = GridBagConstraints.BOTH;
cst.gridx = 0;
cst.gridy = 0;
cst.weightx = 1.0; // --> You miss this for the top panel
cst.weighty = 1.0;
getContentPane().add(pnlTop, cst);
cst = new GridBagConstraints();
cst.fill = GridBagConstraints.HORIZONTAL;
cst.gridx = 0;
cst.gridy = 1;
cst.weightx = 1.0; // You miss this for the bottom panel
cst.weighty = 0.0;
getContentPane().add(pnlBottom, cst);
Further more, if you want to use gridbag layout, I recommend you to try the painless-gridbag library http://code.google.com/p/painless-gridbag/ (I'm the author of that library). It doesn't solve this problem for you (as your problem concerns managing component's size in gridbag layout) but it will save you a lot of typing and make your code easier to maintain
pnlBottom.setPreferredSize(new Dimension(1, 20));
PainlessGridBag gbl = new PainlessGridBag(getContentPane(), false);
gbl.row().cell(pnlTop).fillXY();
gbl.row().cell(pnlBottom).fillX();
gbl.done();
not sure from your question, maybe will help you Top at 70%, Bottom at 30%
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);
}
}
If you may use 3th party libs, you may consider the FormLayout as well. It allows you to specify the height of each row, and the resize behavior.
I did not test this but
FormLayout layout = new FormLayout(
"pref", //columns
"50dlu:grow(0.2)","25dlu:grow(0.1)" //rows
);
might do the trick. More information on the syntax can be found in the JGoodies Forms pdf

Categories

Resources