1

I'm trying to make a little game with JButton objects. My problem is, when I add buttons to my panel, they don't position where I need them. To be more clear.

This is the Image I have :

enter image description here

Here's my code :

My main class which extends JFrame adds a new Board1 which extends JPanel

public class Main2 extends JFrame {

 public Main2() {
    setVisible(true);
    setSize(500, 500);
    add(new Board1());
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setTitle("Zombicide");
    setResizable(false);
 }

 public static void main(String[] args) {
    new Main2();
 }
}

My Board class which extends JPanel and adds some Zone objects which extend JButton.

public class Board1 extends JPanel implements Board {

private List<Zone> zones = new ArrayList<Zone>();

  public Board1() {
    zones.add(new Zone(1, false, true, null, "/zone1D1C.jpg", 0, 0, this));
    zones.add(new Zone(2, false, false, null, "/zone2D1C.jpg", 150, 0, this));
    zones.add(new Zone(3, false, false, null, "/zone3D1C.jpg", 300, 0, this));
    zones.add(new Zone(4, true, false, null, "/zone4D1C.jpg", 0, 150, this));
    zones.add(new Zone(5, false, false, null, "/zone5D1C.jpg", 300, 150, this));
    zones.add(new Zone(6, true, false, null, "/zone6D1C.jpg", 0, 300, this));
    zones.add(new Zone(7, true, false, null, "/zone7D1C.jpg", 150, 300, this));
    zones.add(new Zone(8, false, false, null, "/zone8D1C.jpg", 300, 300, this));
  }
}

And finally my zone class which extends JButton

public class Zone extends JButton implements ActionListener {

private final Zone zone;
private final Board board;
private Integer id;
private boolean piece;
private boolean egout;
private Integer x;
private Integer y;
private Integer x_end;
private Integer y_end;

public Zone(Integer id, boolean piece, boolean egout, Dalle[] dalles, List<Connexion> connexions, String image_name, Integer x, Integer y, Board board) {
zone = this;
addMouseListener(new TAdapter());
this.board = board;
this.piece = piece;
this.egout = egout;
this.id = id;
this.setLayout(null);
this.setBorder(null);
this.setText(null);
ImageIcon ii = new ImageIcon(this.getClass().getResource(image_name));
this.setIcon(ii);
this.x = x;
this.y = y;
this.setBounds(x, y, ii.getIconWidth(), ii.getIconHeight());
this.x_end = x + ii.getIconWidth();
this.y_end = y + ii.getIconHeight();
this.setSize(ii.getIconWidth(), ii.getIconHeight());
}

private class TAdapter extends MouseAdapter {

  @Override
  public void mouseClicked(MouseEvent e) {
    if (gotoZone()) {
      ...
    } else {
      System.out.println("error");
    }
  }
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
pred
  • 185
  • 1
  • 14
  • 1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example). 2) Java GUIs have to work on different OS', screen size, screen resolution etc. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). 3) Provide ASCII art, or a simple drawing, of the intended layout of the GUI. – Andrew Thompson Nov 13 '14 at 09:12
  • By the looks of those numbers, this could be achieved using a 3x3 `GridLayout` with a `JLabel` in the center (as an invisible component). – Andrew Thompson Nov 13 '14 at 09:15
  • I can't use a GridLayout because it's a special board game. And I don't want any space between my buttons I will add a screen – pred Nov 13 '14 at 09:23
  • And @AndrewThompson my code is working as it post, except for imports ! – pred Nov 13 '14 at 09:29
  • 2
    Did you consider to use GridBagLayout ? You can avoid space between buttons and spread a button over multiple cells. – Fabien Thouraud Nov 13 '14 at 09:33
  • *"my code is working as it post"* Doesn't work here (or anywhere else that the user does not have those images on the right path). One way to get images for an example, is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). Also an MCVE needs to be a) Complete (ie. includes imports) and b) A single source file. – Andrew Thompson Nov 13 '14 at 09:33
  • @FabienThouraud I think you have 'hit the nail on the head' with the suggestion of `GridBagLayout`. +1 – Andrew Thompson Nov 13 '14 at 09:35

2 Answers2

2

The GridBagLayout is the best suitable layout for what you try to achieve. It could be something like this :

public class Board1 extends JPanel implements Board {
    public Board1() {
        super();
        this.setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridx = 0;
        constraints.gridy = 0;
        this.add(new Zone(...), constraints);
        constraints.gridx = 1;
        constraints.gridy = 0;
        this.add(new Zone(...), constraints);
        // You caught the point I think
    }
}

You have a good tutorial made by Oracle here.

Fabien Thouraud
  • 909
  • 1
  • 11
  • 21
2

enter image description here

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;

public class ZombiecideLayout {

    private JComponent ui = null;

    ZombiecideLayout() {
        initUI();
    }

    public void initUI() {
        if (ui != null) {
            return;
        }

        ui = new JPanel(new GridBagLayout());
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        try {
            URL dayAddress = new URL("https://i.stack.imgur.com/OVOg3.jpg");
            URL nightAddress = new URL("https://i.stack.imgur.com/lxthA.jpg");
            BufferedImage biDay = ImageIO.read(
                    dayAddress).getSubimage(180, 0, 300, 300);
            BufferedImage biNight = ImageIO.read(
                    nightAddress).getSubimage(180, 0, 300, 300);

            GridBagConstraints gbc = new GridBagConstraints();
            Insets pad = new Insets(0,0,0,0);

            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = pad;
            gbc.gridwidth = 1;
            gbc.gridheight = 1;
            JButton b1 = new JButton();
            b1.setContentAreaFilled(false);
            b1.setBorder(null);
            b1.setMargin(pad);
            b1.setIcon(new ImageIcon(biDay.getSubimage(0, 0, 100, 100)));
            b1.setRolloverIcon(new ImageIcon(biNight.getSubimage(0, 0, 100, 100)));
            ui.add(b1, gbc);

            gbc.gridx = 1;
            JButton b2 = new JButton();
            b2.setContentAreaFilled(false);
            b2.setBorder(null);
            b2.setMargin(pad);
            b2.setIcon(new ImageIcon(biDay.getSubimage(100, 0, 100, 100)));
            b2.setRolloverIcon(new ImageIcon(biNight.getSubimage(100, 0, 100, 100)));
            ui.add(b2, gbc);

            gbc.gridx = 2;
            JButton b3 = new JButton();
            b3.setContentAreaFilled(false);
            b3.setBorder(null);
            b3.setMargin(pad);
            b3.setIcon(new ImageIcon(biDay.getSubimage(200, 0, 100, 100)));
            b3.setRolloverIcon(new ImageIcon(biNight.getSubimage(200, 0, 100, 100)));
            ui.add(b3, gbc);

            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.gridwidth = 2;
            JButton b4 = new JButton();
            b4.setContentAreaFilled(false);
            b4.setBorder(null);
            b4.setMargin(pad);
            b4.setIcon(new ImageIcon(biDay.getSubimage(0, 100, 200, 100)));
            b4.setRolloverIcon(new ImageIcon(biNight.getSubimage(0, 100, 200, 100)));
            ui.add(b4, gbc);

            gbc.gridx = 2;
            gbc.gridy = 1;
            gbc.gridwidth = 1;
            JButton b5 = new JButton();
            b5.setContentAreaFilled(false);
            b5.setBorder(null);
            b5.setMargin(pad);
            b5.setIcon(new ImageIcon(biDay.getSubimage(200, 100, 100, 100)));
            b5.setRolloverIcon(new ImageIcon(biNight.getSubimage(200, 100, 100, 100)));
            ui.add(b5, gbc);

            gbc.gridx = 0;
            gbc.gridy = 2;
            JButton b6 = new JButton();
            b6.setContentAreaFilled(false);
            b6.setBorder(null);
            b6.setMargin(pad);
            b6.setIcon(new ImageIcon(biDay.getSubimage(0, 200, 100, 100)));
            b6.setRolloverIcon(new ImageIcon(biNight.getSubimage(0, 200, 100, 100)));
            ui.add(b6, gbc);

            gbc.gridx = 1;
            JButton b7 = new JButton();
            b7.setContentAreaFilled(false);
            b7.setBorder(null);
            b7.setMargin(pad);
            b7.setIcon(new ImageIcon(biDay.getSubimage(100, 200, 100, 100)));
            b7.setRolloverIcon(new ImageIcon(biNight.getSubimage(100, 200, 100, 100)));
            ui.add(b7, gbc);

            gbc.gridx = 2;
            JButton b8 = new JButton();
            b8.setContentAreaFilled(false);
            b8.setBorder(null);
            b8.setMargin(pad);
            b8.setIcon(new ImageIcon(biDay.getSubimage(200, 200, 100, 100)));
            b8.setRolloverIcon(new ImageIcon(biNight.getSubimage(200, 200, 100, 100)));
            ui.add(b8, gbc);

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                ZombiecideLayout o = new ZombiecideLayout();

                JFrame f = new JFrame("Zombiecide Layout");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433