4

I have written a short game. In the existing implementation I have a GridBagLayout with buttons located as chess board. Each button occupies the whole grid. Game works fine. My next task is to change the board to be consist of hexagonal buttons, not rectangles like currently. I completely don't know how to do this. Buttons should look like these on the picture: target

SigGP
  • 716
  • 1
  • 11
  • 24
  • 2
    Those aren't hexahedrons. – Dawood ibn Kareem May 16 '17 at 22:43
  • 2
    Actually, there are a lot of posts about the shape of JButtons, however I did not want to fish through them all to find an answer. [These might help](http://stackoverflow.com/search?q=%5Bjava%5D+%5Bjbutton%5D+shape) –  May 16 '17 at 22:45
  • Possible duplicate of [Buttons in shapes other than rectangles](http://stackoverflow.com/questions/10785416/buttons-in-shapes-other-than-rectangles) –  May 16 '17 at 22:50
  • 2
    You have two problems, the first is generating the shape and how you might do this, the second is getting the align. Even if you use a `JButton` and either paint the shape yourself, use a `Border` or `Image`, it's still a rectangle, so pretty much all the layout managers won't lay them out the way you want. Either this will require a full custom painting route or a custom layout manager as well – MadProgrammer May 16 '17 at 23:03
  • 2
    See also [*creating 10.000 connected hexagon page*](http://stackoverflow.com/q/3687176/230513); use `Polygon::contains` for hit testing.. – trashgod May 17 '17 at 02:01
  • Can you please post your code? I'll see what I can do then. –  Jul 28 '17 at 02:57

1 Answers1

2

This isn't the prettiest way, but It will at least give you an Idea:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class HexagonPattern extends JPanel {
    private static final long serialVersionUID = 1L;
    private static final int ROWS = 7;
    private static final int COLUMNS = 7;
    private HexagonButton[][] hexButton = new HexagonButton[ROWS][COLUMNS];


    public HexagonPattern() {
        setLayout(null);
        initGUI();
    }


    public void initGUI() {
        int offsetX = -10;
        int offsetY = 0;

        for(int row = 0; row < ROWS; row++) {
            for(int col = 0; col < COLUMNS; col++){
                hexButton[row][col] = new HexagonButton(row, col);
                hexButton[row][col].addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        HexagonButton clickedButton = (HexagonButton) e.getSource();
                        System.out.println("Button clicked: [" + clickedButton.getRow() + "][" + clickedButton.getCol() + "]");
                    }
                });
                add(hexButton[row][col]);
                hexButton[row][col].setBounds(offsetY, offsetX, 105, 95);
                offsetX += 87;
            }
            if(row%2 == 0) {
                offsetX = -52;
            } else {
                offsetX = -10;
            }
            offsetY += 76;
        }
    }

    public static void main(String[] args) {
        HexagonPattern hexPattern = new HexagonPattern();
        JFrame frame = new JFrame();
        frame.setTitle("Hexagon Pattern");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(new Point(700, 300));
        frame.add(hexPattern);
        frame.setSize(550, 525);
        frame.setResizable(false);
        frame.setVisible(true);
    }

    //Following class draws the Buttons
    class HexagonButton extends JButton {
        private static final long serialVersionUID = 1L;
        private static final int SIDES = 6;
        private static final int SIDE_LENGTH = 50;
        public static final int LENGTH = 95;
        public static final int WIDTH = 105;
        private int row = 0;
        private int col = 0;

        public HexagonButton(int row, int col) {
            setContentAreaFilled(false);
            setFocusPainted(true);
            setBorderPainted(false);
            setPreferredSize(new Dimension(WIDTH, LENGTH));
            this.row = row;
            this.col = col;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Polygon hex = new Polygon();
            for (int i = 0; i < SIDES; i++) {
                hex.addPoint((int) (50 + SIDE_LENGTH * Math.cos(i * 2 * Math.PI / SIDES)), //calculation for side
                        (int) (50 + SIDE_LENGTH * Math.sin(i * 2 * Math.PI / SIDES)));   //calculation for side
            }       
            g.drawPolygon(hex);
        }

        public int getRow() {
            return row;
        }

        public int getCol() {
            return col;
        }
    }
}

Test it out!

This program consists of 2 classes:

  1. HexagonButton, which uses Graphics to draw a hexagon into a JButton. It also returns the row and column values when getRow or getCol are called.

  2. HexagonPattern, which is the main class. It makes the pattern by laying them out with setBounds(x, y, width, height). It uses an ActionListener to print the coordinates of the Hexagon clicked, by calling getRow and getCol.

Like I said, this isn't the greatest program. If you want to make the hexagons smaller, then you'll have to change many variables.