-4

I'm using Java to make an n-puzzle game (see http://en.wikipedia.org/wiki/N-puzzle). I currently have it working within a JFrame such that the JFrame contains a JTextField which takes in the number of the tile to move, then moves it; a JTextArea which contains a string passed to it from a method which turns the contents of the puzzle(which is a 2-D array of objects called Tile); and a couple of JButtons to restart or reshuffle the puzzle. The code is below if you wish to try it (only works for square puzzles i.e. equal no. of rows and columns).

Here's my problem - I want to change the way the JFrame works so that instead of a TextArea and TextField I want it to have an array of JButtons instead which link to relevant tiles in the puzzle. Sorta like this;

 PuzzleFrame thisPuzzleFrame = new PuzzleFrame(4, 4);
 JButton[][] theseTiles = new JButton[4][4];
 int p = 0, o = 0;
    while (p < 4) {
        for (int i = 0; i < 15; i++) {
            for (o = 0; o < 4; o++) {
                //link each button to an element of the PuzzleFrame Tile[][]
                tiles[p][o] = new JButton(thisPuzzleFrame.Frame[p][o]); // this should refer a JButton to a Tile
                tiles[p][o].setBounds(o, p, 4, 4);
                        tiles[p][o].setText(Tile.toString(thisPuzzleFrame.Frame[p][o]) // this sets the face on the button to be the number associated with the Tile in PuzzleFrame.Frame[p][o]     

                i++;
            }
            o = 0;
            p++;
            i--;
        }
    }

And then have an ActionListener which, when pressed, calls to the slideTile method in the PuzzleFrame class like this;

 //set up ActionListener
 PuzzleFrame.slideTile(thisPuzzleFrame, this); //method to slide the tile that has been pressed

However, I'm getting stuck trying to get any of this to work. If anyone could, I would love to learn how to link a JButton to a Tile like that, and find some dynamic way of adding any number of JButtons to a JFrame so that if the user wants to do a 5x5 puzzle, the relevant JButtons will appear on the JFrame in the correct places.

I'm not having any compiler problems etc. I am just asking about the theory of linking my object Tile to a JButton as is stated above. What follows is just snippets of the code as it is currently, in case it is needed

This should be the relevant methods and objects in case someone wishes to view them - they are not part of the question but merely background to it

   public class GUI extends JFrame {


        private static final long serialVersionUID = 1L;
        public static JLabel label;
        public static JTextField TextField;
        public static JTextArea OutPut;
        static int gRow, gColumn;
        static PuzzleFrame thisPuzzleFrame;
        public static JButton yes, no, shuffle, reset, setSolved;

        public GUI() {




            super("N Puzzle");
            setSize(500, 500);
            setVisible(true);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBackground(Color.black);
            setResizable(false); 

            setLayout(new FlowLayout());

            label = new JLabel(
                    "Please enter the number of rows you would like to use: ");
            add(label);

            TextField = new JTextField(18);
            add(TextField);
            TextField.requestFocus();
            TextField.setVisible(true);




            final ActionListener InputListener1 = new ActionListener() {
                public void actionPerformed(ActionEvent evt) {

                    gRow = Integer.parseInt(GUI.TextField.getText());

                    label.setText("Please enter the number of columns you would like to use: ");
                    TextField.setText("");              


                    ActionListener InputListener2 = new ActionListener() {
                        public void actionPerformed(ActionEvent evt) {



                            gColumn = Integer.parseInt(GUI.TextField.getText());
                            label.setText("Please select the tile you wish to move: ");

                            shuffle.setVisible(true);
                            setSolved.setVisible(true);
                            reset.setVisible(true);

                            TextField.setText("");
                            thisPuzzleFrame = new PuzzleFrame(gRow, gColumn);

                            try {
                                 PuzzleFrame.shufflePuzzle(GUI.thisPuzzleFrame,
                                 100000);
                            } catch (Exception e) {
                            }

                            OutPut.setText(PuzzleFrame.toString(thisPuzzleFrame));


                            ActionListener InputListener3 = new ActionListener() {
                                public void actionPerformed(ActionEvent evt) {

                                    int tileNo = Integer.parseInt(TextField
                                            .getText());

                                    try {
                                        PuzzleFrame.findAndSlide(thisPuzzleFrame,
                                                tileNo);
                                    } catch (Exception e) {
                                    }

                                    OutPut.setText(PuzzleFrame
                                            .toString(thisPuzzleFrame));
                                    TextField.setText("");
                            TextField.removeAll();
                            TextField.addActionListener(InputListener3);
                        }

                    };
                    TextField.removeAll();
                    TextField.addActionListener(InputListener2);
                }
            };

            TextField.addActionListener(InputListener1);

            yes = new JButton("Yes");
            no = new JButton("No");

            yes.setVisible(false);
            no.setVisible(false);
            add(yes);
            add(no);



        }


        public Tile(int rowIn, int columnIn, int no) {

            row = rowIn;
            column = columnIn;
            Number = no;
        }



        public static String toString(Tile tile) {


            String thisTile;

            if (tile != PuzzleFrame.empty) {
                thisTile = String.valueOf(tile.Number);
            } else {
                thisTile = " ";
            }

            return thisTile;

        }

    }



    public class PuzzleFrame {


        static Tile empty;
        int rowLength, columnLength;
        Tile[][] Frame;

        public PuzzleFrame(int rows, int columns) {

            rowLength = rows;
            columnLength = columns;

            Frame = MakePuzzleFrame(this);

        }

            public Tile[][] MakePuzzleFrame(PuzzleFrame thispuzzle) {

            Tile[][] theTiles = new Tile[thispuzzle.rowLength][thispuzzle.columnLength];


            int p = 0, o = 0;
            while (p < thispuzzle.rowLength) {
                for (int i = 0; i < ((thispuzzle.rowLength * thispuzzle.columnLength)); i++) {
                    for (o = 0; o < thispuzzle.columnLength; o++) {
                        Tile thisTile = new Tile(p, o, (i + 1));
                        thisTile.currentRow = p;
                        thisTile.currentColumn = o;
                        theTiles[p][o] = thisTile;
                        i++;
                    }
                    o = 0;
                    p++;
                    i--;
                }
            }


            empty = new Tile(thispuzzle.rowLength - 1, thispuzzle.columnLength - 1,
                    0);
            theTiles[thispuzzle.rowLength - 1][thispuzzle.columnLength - 1] = empty;
            empty.currentColumn = thispuzzle.rowLength - 1;
            empty.currentRow = thispuzzle.rowLength - 1;

            return theTiles;
        }

 public static void slideTile(PuzzleFrame puzzle, Tile tile)
                throws Exception {

            switch (isMoveAllowed(puzzle, tile)) {

            case 'D': {
                puzzle.Frame[tile.currentRow + 1][tile.currentColumn] = tile;
                puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
                empty.currentColumn = tile.currentColumn;
                empty.currentRow = tile.currentRow;
                tile.currentRow = tile.currentRow + 1;
                break;
            }
            case 'U': {
                puzzle.Frame[tile.currentRow - 1][tile.currentColumn] = tile;
                puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
                empty.currentColumn = tile.currentColumn;
                empty.currentRow = tile.currentRow;
                tile.currentRow = tile.currentRow - 1;
                break;
            }

            case 'L': {
                puzzle.Frame[tile.currentRow][tile.currentColumn - 1] = tile;
                puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
                empty.currentColumn = tile.currentColumn;
                empty.currentRow = tile.currentRow;
                tile.currentColumn = tile.currentColumn - 1;
                break;
            }
            case 'R': {
                puzzle.Frame[tile.currentRow][tile.currentColumn + 1] = tile;
                puzzle.Frame[tile.currentRow][tile.currentColumn] = empty;
                empty.currentColumn = tile.currentColumn;
                empty.currentRow = tile.currentRow;
                tile.currentColumn = tile.currentColumn + 1;
                break;
            }
            case 'N': {
                GUI.OutPut.append("\nInvalid slide!");
            }
            }
        }
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Simon Major
  • 11
  • 1
  • 1
  • 6
  • 6
    Good grief, that's long. Please edit it down to just the *relevant* pieces. That may take you a little time, but you might find your answer in the process. – Michael Petrotta Feb 27 '12 at 00:07
  • @MichaelPetrotta You needn't read through the code in the final code area - it's not the question, just the background to it. I included the full code so that it could be run and compiled if anyone wished to use it. Everything above where I posted the actual code from the program is perfectly valid as a question. – Simon Major Feb 27 '12 at 00:36
  • @MichaelPetrotta - code has been trimmed to the relevant methods and objects. Sorry for it having been too long. If it is still too long, please feel free to tell me and I'll try to cut it back further. – Simon Major Feb 27 '12 at 00:51
  • 1
    For better help sooner, post an [SSCCE](http://sscce.org/). (And in case you are wondering: No, two public classes mashed into one code listing of 229 lines is ***not*** an SSCCE!) – Andrew Thompson Feb 27 '12 at 02:52
  • please learn java naming conventions and stick to them – kleopatra Feb 27 '12 at 11:22

1 Answers1

2

Using a button offers several ways to alter the appearance, in roughly increasing order of difficulty:

  • Change the button's text, as shown in this game and this example.

  • Change the button's Icon, as shown in this example.

  • Override paintComponent(), as shown here.

  • Replace the button's UI delegate entirely, as shown here.

See How to Use Buttons, Check Boxes, and Radio Buttons for more.

Addendum: Once you've got the buttons' appearance settled, see How to Use Actions for more on encapsulating an ActionListener.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045