0

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?

  • It's good to see you using layouts, but do you understand how they work and how they determine component sizes/positions? This might need some more research. You can affect the size of a button by changing it's margins, you can also affect the size of a component using the `ipadx` and `ipady` constraints of `GridBagLayout` – MadProgrammer Mar 29 '17 at 22:57
  • I will definitely do some more research. Thanks for response! – Przemyslav Mar 29 '17 at 23:12
  • *"trying to make a mine sweeper game .. tried to change size of a button"* When the game was set up, or when it was already on screen? I ask because the first code example is changing (or removing) buttons when the GUI is visible, and I don't see how either is relevant to mine sweeper. I have a little (unfinished) 'mine sweeper' code in my junk code project. It creates square buttons by overriding the preferred size, but thereafter it leaves them in place at the exact same size and just changes the text/icon they display, according to the model and state of the game. – Andrew Thompson Mar 30 '17 at 06:37
  • I try to use a trick with setVisible() method and GridBagLayout. I add JButtons and JLabels (parts of Field class) in turns to the GridBagLayout (number of rows and colums is defined by user and it matches to the board), then I set JButtons as visible ( button.setVisible(true) ) and JLabels as unseen ( label.setVisible(false) ). Clicking a button engages a method that makes it disapear ( button.setVisible(false) and label.setVisible(true) ) – Przemyslav Mar 30 '17 at 22:15
  • Edit: I forgot that GridBagLayout has no definition of rows and colums. I add components to raw layout, then I use pack() method. – Przemyslav Mar 30 '17 at 23:47
  • Tip: Add @MadProgrammer (or whoever, the `@` is important) to *notify* the person of a new comment. – Andrew Thompson Mar 31 '17 at 12:25

1 Answers1

1
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

Community
  • 1
  • 1
vip1all
  • 122
  • 11
  • Elimination of stretching is definitely meaningful for reaching the solution , but I'm still having problem with resizing. – Przemyslav Mar 29 '17 at 23:40
  • @Przemyslav You can try `big.setPreferredSize(new Dimension(30, 30));` – vip1all Mar 30 '17 at 00:42
  • Please use code formatting (*not **quote** formatting*) for code and code snippets, structured documents like HTML/XML or input/output. To do that, select the text and **click the `{}` button** at the top of the message posting/editing form. – Andrew Thompson Mar 30 '17 at 06:27
  • *" You can try `big.setPreferredSize(new Dimension(30, 30));`"* See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Mar 30 '17 at 06:28
  • Thanks for answer! Actually setPreferredSize() method does the job for a while, but I will definitely try to change that implementation in a long run. – Przemyslav Mar 30 '17 at 22:02