如何将JButton链接到对象并调用相关方法

问题描述:

我正在使用Java来制作一个n-puzzle游戏(请参阅http://en.wikipedia.org/wiki/N-puzzle)。 我目前有它在JFrame中工作,使得JFrame包含一个JTextField,它接收要移动的图块的编号,然后移动它;一个JTextArea,其中包含一个字符串,该字符串从一个方法中传递给该方法,该方法转动拼图的内容(这是一个名为Tile的对象的二维数组);和几个JButton重新启动或重新洗牌。如果你想尝试它,代码如下(只适用于方形谜题,即等于行数和列数)。如何将JButton链接到对象并调用相关方法

这里是我的问题 - 我想改变JFrame的工作方式,以便代替TextArea和TextField,我希望它有一个JButton数组,而不是链接到拼图中相关的图块。 Sorta像这样;

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--; 
     } 
    } 

然后有一个ActionListener当被按下时,则调用在PuzzleFrame类这样的方法slideTile;

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

但是,我陷入了困境,试图让这个工作。如果有人愿意,我很想学习如何将JButton链接到这样的Tile,并找到一些动态的方式将任意数量的JButton添加到JFrame中,以便如果用户想要做5x5的谜题,相关的JButton将会出现在JFrame上的正确位置。

我没有任何编译器问题等。我只是问关于如上所述链接我的对象瓷砖到JButton的理论。接下来就是代码的片段,因为它是目前的情况下,它是需要

这应该是相关的方法和对象的情况下,有人希望查看他们 - 他们不是问题,但仅仅是背景的一部分它

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!"); 
      } 
      } 
     } 
+6

好悲伤,这很长。请将其编辑为*相关*部分。这可能需要一点时间,但您可能会在过程中找到您的答案。 – 2012-02-27 00:07:45

+0

@MichaelPetrotta您无需通读最终代码区域中的代码 - 这不是问题,只是它的背景。我包含完整的代码,以便可以运行和编译,如果有人希望使用它。上面的所有内容都是我从程序中发布实际代码的完全有效的问题。 – 2012-02-27 00:36:52

+0

@MichaelPetrotta - 代码已被修剪为相关的方法和对象。对不起,它太久了。如果它仍然太长,请随时告诉我,我会尽量减少它。 – 2012-02-27 00:51:20

使用按钮提供了多种方式来改变外观,在困难的顺序大致增加:

  • 更改按钮的文本,如如图所示gameexample

  • 更改按钮的Icon,如此example所示。

  • 重写paintComponent(),如图所示here

  • 完全替换按钮的UI代理,如here所示。

查看How to Use Buttons, Check Boxes, and Radio Buttons了解更多。

附录:一旦你确定了按钮的外观,请参阅How to Use Actions以了解关于封装ActionListener的更多信息。