Inconsistent placement of components (button and checkbox) using GridBagLayout - java

The code below was copied from Oracle tutorials and modified to place components OTHER than buttons--a label and two text fields and an additional button. It produces the form that it should (shown below), so you shouldn't have to scrutinize the first 30 or so lines of code:
If I UNcomment out the two lines that refer to "box" and comment out the adjoining lines that refer to button, look at where the checkbox is placed.
I can't figure out how what's going on. I want the checkbox on the last line, as the code SEEMS to say it MUST be positioned, yet it is NOT.
All I am doing is changing TWO LINES that refer to button to refer instead to checkbox. Are the rules for GridBagLayout component-dependent?? What should I do (and why isn't the code working as is) to get checkbox on bottom line?
public class Testy {
public static void addComponentsToPane(Container pane) {
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 0; c.gridy = 0;
JLabel label = new JLabel("Button 1 ");
pane.add(label, c);
JTextField text = new JTextField("Button 2 ");
c.gridx = 1; c.gridy = 0;
pane.add(text, c);
JButton button = new JButton("Button 3 ");
c.gridx = 2; c.gridy = 0;
pane.add(button, c);
text = new JTextField("LONG Text 4 ");
c.ipady = 40;
c.weightx = 0.0;
c.gridwidth = 3;
c.gridx = 0; c.gridy = 1;
pane.add(text, c);
button = new JButton("5 ");
c.ipady = 0;
c.weighty = 1.0;
c.gridx = 1; c.gridy = 2;
c.gridwidth = 2;
pane.add(button, c);
// Here's the part of the code in question
button = new JButton("666"); // This placement is FINE, at bottom of form.
// JCheckBox box = new JCheckBox("Me?"); // "box" does NOT get placed on last line.
c.weighty = 0;
c.gridx = 0; c.gridy = 3;
c.gridwidth = 1;
// pane.add(box);
pane.add(button, c);
}
Here are the required imports and two methods that I removed so the problem code area above could be seen without scrolling:
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
private static void createAndShowGUI() /* calls addComponentsToPane() */{
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) /* calls createAndShowGUI() */ {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
} }); }
}

// pane.add(box);
pane.add(button, c);
You just have to use the right method:
pane.add(box, c);
See Container#add(Component comp) and Container#add(Component comp, Object constraints).

Related

Issue with changing JButton size

I'm trying to make a mine sweeper game with Swing library (just for training).
I spotted a problem when I tried to change size of a button with setSize() method (part of Container class). One of my previous program was able to handle that (with ActionListener)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonChanger extends JFrame {
JButton big, small, dis;
JLabel message, poof;
public ButtonChanger(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
message = new JLabel("Click to make it");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
add(message, c);
big = new JButton("BIG");
big.setSize(30, 30); // no reaction for this call
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
add(big, c);
small = new JButton("small");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 1;
add(small, c);
dis = new JButton("disapear");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 3;
c.gridy = 1;
add(dis, c);
poof = new JLabel(" poof!");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 3;
c.gridy = 1;
poof.setVisible(false);
add(poof, c);
big.setSize(300,300); // same story
event a = new event();
big.addActionListener(a);
small.addActionListener(a);
dis.addActionListener(a);
}
public class event implements ActionListener{
public void actionPerformed(ActionEvent a){
String op = a.getActionCommand();
if(op.equals("BIG")){
big.setSize(50,50); // finaly!
} else if(op.equals("small")){
small.setSize(10,10);
} else if(op.equals("disapear")){
dis.setVisible(false);
poof.setVisible(true);
}
}
}
public static void main(String args[]){
ButtonChanger gui = new ButtonChanger();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setVisible(true);
gui.setSize(250,250);
gui.setTitle("");
}
}
But when I tried to use same solution here - nothing happened.
import java.util.Random;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Board extends JPanel
implements ActionListener{
private Integer pixelWidth;
private Integer pixelHeight;
public Field[][] board;
private Random generator = new Random();
public Board(int width,int height){ // width - x axis scaled with "button" unit
// height - y axis scaled with "button" unit
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
board = new Field[width][height];
pixelWidth = width * Field.fieldW;
pixelHeight = height * Field.fieldH;
for(int i = 0;i < height;i++)
for(int j = 0;j < width;j++){
board[i][j] = new Field(generator.nextBoolean());
}
for(int i = 0;i < height;i++){
c.fill = GridBagConstraints.HORIZONTAL;
c.gridy = i;
for(int j = 0;j < width;j++){
c.gridx = j;
add(board[i][j].getFieldButton(),c);
add(board[i][j].getFieldLabel(),c);
}
}
/* for(int i = 0;i < height;i++)
for(int j = 0;j < width;j++){
board[i][j].setField();
}*/
}
public void actionPerformed(ActionEvent e){
String co = e.getActionCommand();
if(co.equals(" ")){ // button is single space sign
for(int i = 0;i < 10;i++)
for(int j = 0;j < 10;j++){
board[i][j].setField(); //inside this method is call for setSize() for fieldButton
}
}
}
}
Previously I changed Board class to make it inhetitate after JFrame (set up as main GUI frame in whole code) but that gave me same output as original.
Did I mess up something?
big = new JButton("BIG");
big.setSize(30, 30); // no reaction for this call
c.fill = GridBagConstraints.HORIZONTAL;
There is no reaction for big.setSize... because then in GridBagConstraints you set fill to horizontal, so button will be "stretched" to fill horizontally.
Instead use c.fill = GridBagConstraints.NONE
fill
Used when the component's display area is larger than the component's requested size to determine whether and how to resize the component. Valid values (defined as GridBagConstraints constants) include NONE (the default), HORIZONTAL (make the component wide enough to fill its display area horizontally, but do not change its height), VERTICAL (make the component tall enough to fill its display area vertically, but do not change its width), and BOTH (make the component fill its display area entirely).
You can read more here: https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

Changing where an object is on a GridBagLayout in Java

I am working on a project where I have a requirement that when a button is clicked, an object that is in a GridBagLayer moves to a different spot. Here is my code so far:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class main extends JFrame{
private JButton button,littlebutton;
private JLabel holdred1,holdred2;
private ImageIcon red1,red2;
public main(){
//sets the layout
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//sets the button
button = new JButton("Button");
c.gridx = 0;
c.gridy = 0;
add(button,c);
//sets the image
red1 = new ImageIcon(getClass().getResource("/images/redtile.png"));
red2 = new ImageIcon(getClass().getResource("/images/redtile.png"));
//puts it in the JLabel
holdred1 = new JLabel(red1);
c.gridx = 0;
c.gridy = 0;
add(holdred1, c);
holdred2 = new JLabel(red2);
c.gridx = 1;
c.gridy = 0;
add(holdred2, c);
littlebutton = new JButton("Click Me");
c.gridx = 0;
c.gridy = 0;
add(littlebutton,c);
event e = new event();
littlebutton.addActionListener(e);
}
public class event implements ActionListener {
public void actionPerformed(ActionEvent e){
//code goes here
}
}
public static void main(String args[]){
//displaying the window
main gui = new main();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setSize(575,575);
gui.setVisible(true);
gui.setTitle("Change Spot");
}
}
I don't have much experience with Grid Bag Layouts so I have no clue how to do this, Thanks in advance!
The question is how can I make the button change it's gridx to 1
In GridBagConstraints you specify what position you want the element to take in the grid. You already have done that, in this portion of code
c.gridx = 0;
c.gridy = 0;
add(holdred1, c);
holdred2 = new JLabel(red2);
c.gridx = 1;
c.gridy = 0;
add(holdred2, c);
littlebutton = new JButton("Click Me");
c.gridx = 0;
c.gridy = 0;
But you're telling the layout to place multiple components in the same grid using c.gridx = 0, c.gridy = 0. Every component should have its own cell space so they don't overlap.
I edited your code:
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//sets the button
button = new JButton("Button");
c.gridx = 2;
c.gridy = 2;
add(button, c);
//sets the image
// red1 = new ImageIcon(getClass().getResource("/images/redtile.png"));
// red2 = new ImageIcon(getClass().getResource("/images/redtile.png"));
//puts it in the JLabel
holdred1 = new JLabel("Red1");
c.gridx = 1;
c.gridy = 1;
add(holdred1, c);
holdred2 = new JLabel("Red2");
c.gridx = 1;
c.gridy = 2;
add(holdred2, c);
littlebutton = new JButton("Click Me");
c.gridx = 2;
c.gridy = 1;
add(littlebutton, c);
event e = new event();
littlebutton.addActionListener(e);
I assume that you wanted the labels to be on top of the buttons, so I place they on a side so you could practice it.
Another easy tips, if you want a component to take more than a cell in the table you have to use c.weightx = someValue, c.weighty = someValue.
Take a look: How to use GridBagLayout.

Why is the middle column not showing up?

I am making a simple calculator GUI in Java to start to learn how to use Java. The following code is not working. Only the first column is appearing. Where is the second and third column going?
package Start;
import java.awt.*;
import javax.swing.*;
public class CalculatorGUI {
public static void addComponentsToPane(Container pane) {
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
JLabel label;
JButton button;
label = new JLabel("I'm a calculator");
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 0.0;
c.gridx = 0;
c.gridy = 0;
pane.add(label, c);
button = new JButton("1");
c.gridx = 0;
c.gridy = 1;
pane.add(button, c);
button = new JButton("2");
c.gridx = 1;
c.gridy = 1;
pane.add(button, c);
button = new JButton("3");
c.gridx = 2;
c.gridy = 1;
pane.add(button, c);
button = new JButton("4");
c.gridx = 0;
c.gridy = 2;
pane.add(button, c);
button = new JButton("5");
c.gridx = 1;
c.gridy = 2;
pane.add(button, c);
button = new JButton("6");
c.gridx = 2;
c.gridy = 2;
pane.add(button, c);
button = new JButton("7");
c.gridx = 0;
c.gridy = 3;
pane.add(button, c);
button = new JButton("8");
c.gridx = 1;
c.gridy = 3;
pane.add(button, c);
button = new JButton("9");
c.gridx = 2;
c.gridy = 3;
pane.add(button, c);
}
public static void createAndShowGUI() {
JFrame frame = new JFrame("CalculatorGUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
i tried making the label just say c.gridwidth = 3; but that does the same thing. When i make the width just equal 1 all the buttons appear, but the label is in only in one cell. How do i make the label span 3 columns? Without making the other buttons disappear.
How do i make the label span 3 columns without gridwidth?
c.gridwidth = 3;
You will then need to reset it to 1 before adding other components.
so that it is centered over the '2' button
You will also need to set the text alignment of the label:
label.setHorizontalAlignment(JLabel.CENTER);
You're using
c.gridwidth = GridBagConstraints.REMAINDER;
Which Specifies that the current component is the last component in its column or row.
So comment this line out, and it should work just fine.
Reaf more About GridBagLayout.

Weird layout using GridBagConstraints

I have several methods which create their own component, JButton or JLabel in a JPanel. Then I have a separate method which adds all these JPanels the the JFrame. I also use gridx and gridy on the JPanels to position them how I want. This is: lookreply on the left, then top right the title and below in a 2X2 table quit, restart, pickup and hello. However my current code when run displays a weird, random layout.
The lookreply is on the left, but then to the right is quit, a space, restart then hello all vertical. pickup and title aren't seen. I dont know why this is happening.
Please see my code below.:
public class GUI extends JPanel
{
/**
* Creation of variables used throughout the GUI Class.
*/
//JPanel panel = new JPanel(new GridBagLayout());
private static final long serialVersionUID = 1L;
public static void main(String[] args)
{
GUI g = new GUI();
g.create();
}
private void create()
{
JFrame screen = new JFrame("Dungeon of Doom");
screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
screen.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//set size to full screen.
screen.setExtendedState(Frame.MAXIMIZED_BOTH);
//Add all JPanes to screen
screen.add(lookReply(), c);
c.gridy = 0;
c.gridx = 0;
screen.add(title(), c);
c.gridy = 0;
c.gridx = 1;
c.gridwidth = 2;
screen.add(quit(), c);
c.gridy = 1;
c.gridx = 1;
screen.add(restart(), c);
c.gridy = 1;
c.gridx = 2;
screen.add(pickup(), c);
c.gridy = 2;
c.gridx = 1;
screen.add(hello(), c);
c.gridy = 2;
c.gridx = 2;
screen.setVisible(true);
}
One of the methods (quit)
private JPanel quit()
{
JPanel quitPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JButton quit = new JButton("QUIT");
quitPanel.add(quit, c);
return quitPanel;
}
All the other methods are pretty much the same except the title is a a JLabel and the table iterates to create a 5x5 table of JLabel within its own JPanel. Any help is appreciated!
I have found what was doing this.
As seen in the code I was adding the component before setting the layout.
screen.add(lookReply(), c);
c.gridy = 0;
c.gridx = 0;
whereas it should be
c.gridy = 0;
c.gridx = 0;
screen.add(lookReply(), c);

How to make button expand Java

I`m trying to create a Java Applet, I was looking around on the Java website and I found an nice example which I edited.
In this example there are 3 buttons, One that will be like a header, one that will be like a footer
and one that will be like the body. My problem is that, the middle (body) button will not expand fully.
If you run this code, you will see what I mean.
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;
public class main {
final static boolean shouldFill = true;
final static boolean shouldWeightX = true;
final static boolean RIGHT_TO_LEFT = false;
public static void addComponentsToPane(Container pane) {
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
//natural height, maximum width
c.fill = GridBagConstraints.HORIZONTAL;
}
button = new JButton("hi");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 1;
c.gridy = 0;
c.ipady = 40;
pane.add(button, c);
button = new JButton("Hello, i will not expand");
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0; //request any extra vertical space
c.weightx=1.0;
c.anchor = GridBagConstraints.CENTER; //bottom of space
c.insets = new Insets(10,0,0,0); //top padding
c.gridx = 1; //aligned with button 2
c.gridy = 1; //third row
pane.add(button, c);
button = new JButton("fr");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 0; //reset to default
c.weighty = 1.0; //request any extra vertical space
c.anchor = GridBagConstraints.PAGE_END; //bottom of space
c.insets = new Insets(10,0,0,0); //top padding
c.gridx = 1; //aligned with button 2
c.gridwidth = 2; //2 columns wide
c.gridy = 2; //third row
pane.add(button, c);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("main");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Looks like it's not the middle button's fault, but the bottom button that is not expanding, if you set the bottom button as so c.fill = GridBagConstraints.BOTH; then it takes up the empty space below.
Do you want the middle to be bigger? You might want to change the weight of the bottom button to .5
c.weighty = .5; //request any extra vertical space
and see if that is what you are looking for?
If you want the middle to be much bigger then the top and bottom, you may need to make more grid spaces, so rather then 1,1,1, try 1,3,1 etc
I was looking around on the Java website and I found an nice example which I edited.
So I take it you don't have to use a GridBagLayout?
Use a BorderLayout, make the expandable button at position BorderLayout.CENTER.
http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html

Categories