Having small issues on the positioning of my JLabel components.
Code:
public class delete {
public static void main(String[] args){
GridBagConstraints gbc = new GridBagConstraints();
//Adding the JPanels. Panel for instructions
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
//JLabel for the Instructions.
JLabel label = new JLabel("<html> Instructions: Type in the grades you’ve received, along with the weights they’ll have in the determination of your overall average. <br> After you press ‘Calculate’, the results will show your average so far. <br> Every grade you enter must be a non-negative number, and every percentage/weight you enter must be a positive number :)</html>");
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.weighty = 1;
panel.add(label, gbc);
//JLabel1 for Assingment/Grade/Weight(Percent)
JLabel label1 = new JLabel("<html><pre>Assingment\t\t\t\t\tWeight\t\t\t\t\tPercentage</pre></html>");
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(label1, gbc);
//New frame set
JFrame frame = new JFrame("Grade Calculator");
frame.setVisible(true);
frame.setSize(750,500);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(panel);
}
}
Now right now this positions JLabel (label) at the top of the frame which is what I want. The problem is JLabel (label1) I want label1 to be Slightly below label.
If I set gbc.gridy = 0, label1 shows on top of label making both of the separate collide together.
When I set gbc.gridy = 1, label1 goes all the way to the bottom of the frame.
Now I want label1 just to be slightly under label however I cannot use floats with gridy. How can I fix this?
gbc.weighty = 1; is causing the component to be provided with all the remaining space left over after all the components are laid out. Instead of providing label with this constraint you should give it to label1 only
When you don't provide a gridx/gridy to component, GridBagLayout places the component next to the last component, since no other components have been added, label is placed at the top, but you're also supplying a gridx/gridy of 0 to label1, which is placing at the same location.
Instead, place label at 0x0 and label1 at 0x1
JLabel label = new JLabel("<html> Instructions: Type in the grades you’ve received, along with the weights they’ll have in the determination of your overall average. <br> After you press ‘Calculate’, the results will show your average so far. <br> Every grade you enter must be a non-negative number, and every percentage/weight you enter must be a positive number :)</html>");
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridy = 0;
panel.add(label, gbc);
//JLabel1 for Assingment/Grade/Weight(Percent)
JLabel label1 = new JLabel("<html><pre>Assingment\t\t\t\t\tWeight\t\t\t\t\tPercentage</pre></html>");
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.NORTH;
gbc.weighty = 1;
panel.add(label1, gbc);
You can also effect the position that a component will align to within it's cell through the use of the anchor property.
Have a look at How to Use GridBagLayout for some more details
Without knowing "exactly" what you're doing, I might suggest also having a look at How to Use Tables
//JLabel for the Instructions.
JLabel label = new JLabel("<html> Instructions: Type in the grades you’ve received, along with the weights they’ll have in the determination of your overall average. <br> After you press ‘Calculate’, the results will show your average so far. <br> Every grade you enter must be a non-negative number, and every percentage/weight you enter must be a positive number :)</html>");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weighty = 1;
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(label, gbc);
//JLabel1 for Assingment/Grade/Weight(Percent)
JLabel label1 = new JLabel("<html><pre>Assingment\t\t\t\t\tWeight\t\t\t\t\tPercentage</pre></html>");
gbc.gridx = 0;
gbc.gridy = 1;
panel.add(label1, gbc);
Related
I've been self teaching myself swing for a few days for a project and right now I'm trying to figure out how to position components with a grid bag layout. I got most of it except a few small issues. If anyone could help, it would be very appreciated. I've tried this so many different ways D:
...
titlePanel.setLayout(new GridBagLayout());
titlePanel.setBackground(BLUE);
header = new JLabel ("Gradebook");
header.setLocation(200,400);
header.setFont(new Font("Serif", Font.BOLD, 50));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
titlePanel.add(header,gbc);
date = new Date();
currentDate = new JLabel (fmt.format(date));
currentDate.setFont(new Font("Serif", Font.PLAIN, 14));
ActionListener updateTime = new ActionListener() {
public void actionPerformed (ActionEvent e) {
date = new Date();
currentDate.setText(fmt.format(date));
}
};
Timer timer = new Timer (1000, updateTime);
timer.start();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.CENTER;
titlePanel.add(currentDate, gbc);
JLabel userName = new JLabel ("Username: ");
gbc.gridx = 0;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.EAST;
titlePanel.add(userName, gbc);
JTextField username = new JTextField (10);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.WEST;
titlePanel.add(username, gbc);
JLabel password = new JLabel ("Password: ");
gbc.gridx = 0;
gbc.gridy = 3;
gbc.anchor = GridBagConstraints.EAST;
titlePanel.add(password, gbc);
JPasswordField Password = new JPasswordField (10);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.anchor = GridBagConstraints.WEST;
titlePanel.add(Password, gbc);
JButton login = new JButton ("Login");
gbc.gridx = 0;
gbc.gridy = 4;
gbc.anchor = GridBagConstraints.CENTER;
titlePanel.add(login, gbc);
JButton newAccount = new JButton ("Create New Account");
gbc.gridx = 0;
gbc.gridy = 5;
gbc.anchor = GridBagConstraints.CENTER;
titlePanel.add(newAccount, gbc);
mainFrame.add(titlePanel);
So when I run the code for the login screen, it comes up with this
I need a way to center the username and password so they match up with everything else and also add some blank vertical space between the 2 buttons at the bottom. Sorry if this is a dumb question :|
Your username/password contains two components in two different columns. So if you want all the components centered you have two options:
Create a separate panel for each of the label/text field components. Then you can add the panel as a single component which means it will be placed in the first column with all the other components.
Have all the other component "span" two columns. So now they will take up the same width as the label/text field components. In this case you will need to specify the gridWidth constraint.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information on the various constraints used by GridBagLayout.
also add some blank vertical space between the 2 buttons at the bottom
Again, look at the constraints. You could use the insets constraint.
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 JFframe form in NetBeans 8 / Java 7.
It has a bunch of labels, textboxes, dropdowns, etc.
These are a column on the left size, all staked up on top of each other.
Here's a screenshot:
How can I prevent all those components from sticking to the right and resizing along with the window and at the same time have the preview frame at the far right resize along?
I'm new to Java, and the gridbaglayout was the only I found to align everything properly. I just want the left side to have its components well aligned and not moving around. And I just want the right side, the panel, to resize according to the window resize.
Thank you,
I just want the right side, the panel, to resize according to the window resize.
By default all the columns are divided in equal percentage in each row.
To force the second (right side) column to take the more space, assign it a higher percentage using GridBagConstraints#weightx
gc.weightx = 0.75; // 75%
Don't forget to fill the horizontal space completely using GridBagConstraints#fill
gc.fill = GridBagConstraints.HORIZONTAL;
If you want fixed width for first column then set the preferred size for the left side panel by overriding getPreferredSize() method and assign 100% width to the right side panel.
JPanel leftSidePanel = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(..., ...);
}
}
Have a look at my another post GridBagLayout: How to set fixed column width? that explain it better.
It;s worth reading Swing Tutorial on Solving Common Layout Problems
You need to set the fill constraint to NONE.
Tutorial: How to Use GridBagLayout:
When you add each Component to the panel, it would look something like this (from the tutorial):
JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//For each component to be added to this container:
//...Create the component...
//...Set instance variables in the GridBagConstraints instance...
pane.add(theComponent, c);
you need to ensure that you call:
c.fill = GridBagConstraints.NONE;
for every constraints object for each Component that you add to the panel that you don't want to stretch horizontally.
If you're resusing the same constraints object for each component, you can simply set it once for all if that's you're desired result.
EDIT:
As some others have pointed out, the OP may want the fields to stretch, but only up to a certain limit (which is still not clear at this point). In that case, you would use a combination of
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0;
as already pointed out. Example:
import java.awt.*;
import javax.swing.*;
public class GridBagDemo implements Runnable
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new GridBagDemo());
}
public void run()
{
// 4 components that all have different widths
JButton btnBrowse = new JButton("Browse");
JTextField txfHeight = new JTextField(4);
JTextField txfWidth = new JTextField(10);
JButton btnMore = new JButton("More PDF Attributes");
// the preview pane?
JTextArea txaPreview = new JTextArea(8, 20);
JScrollPane scrPreview = new JScrollPane(txaPreview);
scrPreview.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
GridBagConstraints gbc = new GridBagConstraints();
// we'll use these constraints for all components
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(2,4,2,4);
JPanel panel = new JPanel(new GridBagLayout());
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
panel.add(new JLabel("Source PDF size..."), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(btnBrowse, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
panel.add(new JLabel("Height (in inches):"), gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(txfHeight, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
panel.add(new JLabel("Width (in inches):"), gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(txfWidth, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(btnMore, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.weighty = 1;
panel.add(Box.createVerticalGlue(), gbc);
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
panel.add(new JLabel("Preview"), gbc);
gbc.gridx = 2;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 8; // some number that's > the number of entry rows
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
panel.add(scrPreview, gbc);
JFrame frame = new JFrame("GrigBag Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
the gridbaglayout was the only I found to align everything properly.
The MigLayout manager can do that easily. It also provides much better portability.
Notice the usage of related gaps (r), dialog insets (dialog) and logical pixels (lp).
These units are translated to pixels accordingly. On the other hand, GridbagLayout
sets spaces directly in pixels which is inadequate, e.g. changing font or resolution
will affect the layout.
See to following code example:
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutPreview2 extends JFrame {
public MigLayoutPreview2() {
initUI();
setTitle("Design preview");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
JPanel pnl = new JPanel(new MigLayout("ins dialog, wrap"));
pnl.add(new JLabel("Source PDF file..."), "pad 0 -5lp 0 0");
pnl.add(new JButton("Browse"), "growx");
pnl.add(new JLabel("Height (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JLabel("Width (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JButton("More PDF attributes"), "growx");
pnl.add(new JSeparator(), "pad 0 -5lp 0 0, gaptop r, growx");
pnl.add(new JLabel("Set bounding box..."), "pad 0 -5lp 0 0");
pnl.add(new JComboBox(), "growx");
pnl.add(new JSeparator(), "pad 0 -5lp 0 0, gaptop r, growx");
pnl.add(new JLabel("Sheet size..."), "pad 0 -5lp 0 0");
pnl.add(new JComboBox(), "growx");
pnl.add(new JLabel("Height (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JLabel("Width (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JSeparator(), "pad 0 -5lp 0 0, gaptop r, growx");
JPanel rpnl = new JPanel();
rpnl.setBorder(BorderFactory.createEtchedBorder());
pnl.add(rpnl, "cell 2 0, w 90, spany, pushx, grow");
add(pnl);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutPreview2 ex = new MigLayoutPreview2();
ex.setVisible(true);
}
});
}
}
I have reproduced part of your screenshot and have also kept the indents.
Horizontal separators do not stretch completly, since I believe this is not
optimal design. The design is also improved by eliminating the huge spaces
between labels and text fields.
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.
I have a GridBagLayout, and for some reason my JTextArea has decided that it doesn't want to listen to gridbag's ratio for with, and when create the panel which contains the layout my textbox grows till it takes up 1/2 of the screen. Heres some code:
tp = new JTabbedPane();
tp.setFont(Main.f);
//Adds tabs with several buttosn to my tabbed pane
for(Menu menu : FileManager.menus){
JPanel tmp = new JPanel();
int s = (int) Math.ceil(Math.sqrt(menu.products.size()));
tmp.setLayout(new GridLayout(s,s));
for(Product p : menu.products){//Act as
p.setFont(Main.f);
p.addActionListener(this);
tmp.add(p);
}
tp.addTab(menu.name,null,tmp,null);
}
receipt.setBorder(BorderFactory.createEtchedBorder());
//starting up with GridBag
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.ipadx = 0;
gbc.ipady = 0;
//sets up and adds the JTabbedPane
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 0.8;
gbc.weighty = 0.8;
add(tp,gbc);
//sets up and adds receipt - The one that takes up half the screen
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 0.2;
receipt.setEditable(false);
receipt.setText("Ticket number: 0\n" +
"Transaction number: 0\n");
receipt.setLineWrap(true);
add(receipt,gbc);
//sets up and adds a JPanel that has a bunch of buttons on it(Uses gridlayout)
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.weightx = 1;
gbc.weighty = 0.2;
add(buttons,gbc);
buttons.setLayout(new GridLayout(1,8));
createButton(newtable);
createButton(remove);
for(JButton a : quicks)
createButton(a);
createButton(pay);
createButton(exit);
revalidate();
repaint();
When I change the TextArea to a blank JButton it doesn't take up much space at all. Basically the space is filled by the object on the right. How do I tell gridbag that I want my left object to span 4/5ths of the screen, and the right object to span the last 1/5th? In this version I attempt to do so using weighting, in my original version I attempted to do so using cells, so the left object was at gridx=0 gridwidth = 4, and the right object was gridx = 4 gridwidth = 1
Neither way worked. I am also open to alternate ideas(like better layouts, or a JTable?)
Thanks for your help,
Chase
What it's doing
Dimensions for what it should do
If you are not fixed on precisely 4/5 and 1/5 ratio, you can use BorderLayout and place buttons to the center and text area to the East.
Border layout will display the text area as wide as you supply - specify preferred size (width, you can set height to whatever number you want, border layout will ignore it). The rest of the space is then taken up by buttons panel.
You can learn more about border layout here: http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html