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.)
my problem is that although the scroll bar is appearing on the specific panel I want it to it's not extending as labels are added. I would like it to extend when the labels start going off the panel that they are being added to.
I have a main JPanel 'panel' which uses GridBagLayout, within that I have 5 other panels, the ones that needs a scroll bar is boardPanel which has null value for setLayout()
panel = new JPanel();
panel.setLayout(new GridBagLayout());
...
1Panel = new JPanel();
1Panel.setPreferredSize(new Dimension(480, 800));
1Panel.setLayout(null);
scrollPanel = new JScrollPanel(1Panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
...
c.weighty = 1.0;
c.weightx = 0.6;
c.gridx = 0;
c.gridy = 0;
c.gridheight = 3;
panel.add(scrollPanel, c);
...
I hope this is enough information, thank you so much for your help in advance.
Don't use a null layout!!!
Don't use setPreferredSize()!!!
Scrollbars will appear when the preferred size of the component is greater than the size of the scroll pane. By hardcoding a size you break this functionality.
Use a layout manager and the preferred size will change dynamically as you add components to the panel.
Read the Swing tutorial on Layout Managers
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));
I want to shorten my text field so it doesn't stretch to to the end of my jframe so this is how it looks now:
How do control the width of the textfield so it does't streatch like that I tried setPreferedSize() and setSize() yet they didn't work??
#Override
public void run() {
JFrame frame = new JFrame("Test Calculator");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(500, 500);
JPanel panel = new JPanel(new GridBagLayout());
frame.getContentPane().add(panel, BorderLayout.NORTH);
GridBagConstraints c = new GridBagConstraints();
JLabel testLabel = new JLabel("Enter Score For Test 1: ");
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(40, 15, 15, 0);
panel.add(testLabel , c);
JTextField txtField1 = new JTextField("TextField");
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = .5;
panel.add(txtField1 , c);
}
You're telling the layout that the text field must fill horizontally, so that's what it does. Replace
c.fill = GridBagConstraints.HORIZONTAL;
by
c.fill = GridBagConstraints.NONE;
First and foremost, get rid of this:
frame.setSize(500, 500);
Instead let your components and layout managers size themselves by calling pack() on your JFrame after filling it and before setting it visible.
Next, consider either adding an empty border around your main container, or else adding an empty JLabel to your GridBagLayout using container.
You can also give your JTextField appropriate insets to give a cushion around it.
c.insets = new Insets(40, 15, 15, 40);
panel.add(txtField1, c);
You can change how many columns a particular component takes up by changing GridBagConstraints gridwidth field.
//this would make the next component take up 2 columns
c.gridwidth = 2;
You could have a jpanel and set its dimensions and layout, then add the elements to that panel and add the panel to your jframe.
There are different layout types that can be used depending on what you need to be done. I usually like to use Box's. They have methods that allow you to create horizontal/vertical struts, create rigid areas(this is what I usually use)
Box box1 = Box.createHorizontalBox();
Box box2 = Box.createVerticalBox();
box1.add(Box.createRigidArea(new Dimension(30,0)));
box1.add(testLabel);
box1.add(Box.createRigidArea(new Dimension(30,0)));
box1.add(txtField1);
box1.add(Box.createRigidArea(new Dimension(30,0)));
box2.add(Box.createRigidArea(new Dimension(0,30)));
box2.add(box1);
box2.add(Box.createRigidArea(new Dimension(0,30)));
JFrame.add(box2);
Check this link out for descriptions and how to use all the different kinds of layouts: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Is there any method I could implement that will ensure each button within the pane maintains a minimum height? I have attempted using itembutton.setSize() method but it has no effect.
JPanel itemPanel = new JPanel();
itemPanel.setLayout(new GridLayout(0,1));
for(final Item i: list){
JButton itemButton = new JButton(i.getName());
itemPanel.add(itemButton);
}
JScrollPane itemPane = new JScrollPane(itemPanel);
itembutton.setMinimumSize(minimumSize) ?
Edit: Just found that, as this java tutorial seems to tell, there is no way to do that with GridLayout.
Each component takes all the available space within its cell, and each cell is exactly the same size
So I guess you'll have to try another layout. I can suggest (don't know if it's well suited but it works) GridBagLayout. Example with 2 buttons:
itemPanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.weightx = 0.5;
itemPanel.add(new JButton("A"), c);
c.gridx = 1;
c.weightx = 0.5;
itemPanel.add(new JButton("B"), c);
Have a look to http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html