Java 类层次结构使JTextField输入启动方法调用

Java 类层次结构使JTextField输入启动方法调用,java,swing,Java,Swing,我和我的团队在我们选择的项目主题上有一些问题。在编辑我们的程序时,我弄得有点乱,我们不确定各个类应该如何准确地按照最佳实践相互交流,或者看到我们想要的输出 我们目前的问题是,尝试从JTextField输入n、w、s、e表示方向,然后作为keyPressed方法的参数,该方法采用字符串,然后调用适当的move方法,对数组/迷宫的行和列采用int值,并在迷宫中移动字符方块。我们希望TextPanel类中来自direction JTextField对象的输入作为两个keyPressed方法的参数,其中

我和我的团队在我们选择的项目主题上有一些问题。在编辑我们的程序时,我弄得有点乱,我们不确定各个类应该如何准确地按照最佳实践相互交流,或者看到我们想要的输出

我们目前的问题是,尝试从JTextField输入n、w、s、e表示方向,然后作为keyPressed方法的参数,该方法采用字符串,然后调用适当的move方法,对数组/迷宫的行和列采用int值,并在迷宫中移动字符方块。我们希望TextPanel类中来自direction JTextField对象的输入作为两个keyPressed方法的参数,其中它将采用字符串n、w、s、e;然后理想地

最初,我们将所有逻辑都放在一个类中,而没有GUI,这将允许我们穿越迷宫,因此问题在于我们的GUI知识以及如何正确地增加编程以进行测试

认识到这是一个相当模糊的问题,但希望了解如何更好地组织这个程序,让JTextField输入调用其他两个方法

示例代码:

package Project;

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

//Creates a Maze Driver object, which adds a Dungeon and TextPanel 

public class MazeDriver 
{
 public static void main(String[] args)
 {
    MazeDriver mazeDriver = new MazeDriver();   
 }

public MazeDriver(){  
    JFrame frame = new JFrame();
    frame.setTitle("Maze Game");
    frame.add(new Dungeon());
    frame.setSize(180, 200);
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    TextPanel panel = new TextPanel();
    panel.setBackground (Color.white);
    panel.setPreferredSize (new Dimension (800, 400));    

    frame.getContentPane().add(panel);
    frame.pack();              
 }               
}

package Project;

//Creates the maze to be traversed 

public class Maze {
    private int[][] grid; 

    public Maze()
    {
        grid = new int[][]  { {0, 1, 0, 0, 0},
                              {0, 1, 0, 1, 0},
                              {0, 1, 0, 1, 0},
                              {0, 1, 0, 1, 0},
                              {0, 0, 0, 1, 2} };
    }

    public int[][] getGrid(){
        return grid;
    } 
}

package Project;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;
import javax.swing.*;

public class Dungeon extends JPanel
{
    private Image grass, wall, boss;
    private Maze m;
    private Player p;

    public Dungeon()
    {
        m = new Maze();
        p = new Player();

        ImageIcon img = new ImageIcon("grass.png");
        grass = img.getImage();

        img = new ImageIcon("wall.png");
        wall = img.getImage();

        img = new ImageIcon("boss.png");
        boss = img.getImage();

    }



    @Override
    public void paint(Graphics g)
    {
        super.paint(g);

        //for the dimensions of the maze array

        for(int x = 0; x < m.getGrid().length; x++)
        {
            for(int y = 0; y < m.getGrid()[x].length ;y++)
            {

               //if 2 meaning the boss square; 1 meaning a wall, 
                //0 meaning grass/maze path - draw the appropriate tile

               if(m.getGrid()[y][x] == 2) 
                   g.drawImage(boss, x*32, y*32, null);
               if(m.getGrid()[y][x] == 1)
                   g.drawImage(wall, x*32, y*32, null);
               if(m.getGrid()[y][x] == 0)
                   g.drawImage(grass, x*32, y*32, null);
            }
            g.drawImage(p.getPlayer(), p.getTileX()*32, p.getTileY()*32, null);
        }
    }

//public class Movement //implements ActionListener 
//{

        public int moveNorth(int row, int column){

        //if not falling off maze upwards

        if (row > 0)

          //if tile above is not a wall (1 value in array)  
        { if(m.getGrid()[row-1][column] != 1)
          {
            p.move(0, -1); 
          } else
            {
                System.out.println("You've hit a wall."); 
            }
        } else
          {
            System.out.println("You've hit a wall.");
          }
        return row;
        }

        //if not falling off maze downwards
        public int moveSouth(int row, int column){
            if (row < m.getGrid().length-1)
                //if tile below is not a wall (1 value in array)  
            { if(m.getGrid()[row+1][column] != 1)
              {
                p.move(0, 1);
              } else
                {
                    System.out.println("You've hit a wall.");
                }
            } else
              {
                System.out.println("You've hit a wall.");
              }
            return row;
        }

        //if not falling off maze to right
        public int moveEast(int row, int column){
            if (column < m.getGrid()[row].length-1)
                //if tile to right is not a wall (1 value in array)  
            { if(m.getGrid()[row][column+1] != 1)
              {
                p.move(1, 0);
              } else
                {
                    System.out.println("You've hit a wall.");
                }
            } else
              {
                System.out.println("You've hit a wall.");
              }
            return column;
        }

        //if not falling off maze to left
        public int moveWest(int row, int column){
            if (column > 0)
                //if tile to left is not a wall (1 value in array)  
            { if(m.getGrid()[row][column-1] != 1)
              {
                p.move(-1, 0);
              } else
                {
                    System.out.println("You've hit a wall.");
                }
            } else
              {
                System.out.println("You've hit a wall.");
              }
            return column;
        }

        public void keyPressed(String temp){
            Scanner scan = new Scanner(System.in);
            int row = 0, column = 0;

            while ((row != m.getGrid().length-1) || 
                    (column != m.getGrid()[0].length-1))
            {   
                temp = scan.nextLine();
                if(temp.equals("n"))
                    row = moveNorth(row, column);
                if(temp.equals("e"))
                    column = moveEast(row, column);
                if(temp.equals("s"))
                    row = moveSouth(row, column);
                if(temp.equals("w"))
                    column = moveWest(row, column);
                else
                    //TO DO: implement into GUI text field
                    System.out.println("Invalid Direction"); 
            }
        }
        /*
        @Override
        public void actionPerformed (ActionEvent e){
            Object source = e.getSource();
            if (source == 
        }
        */
//}
}
package Project;

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

public class TextPanel extends JPanel {

    //private Dungeon d;

    private JLabel directionLabel; //shows instructions for movement
    private JLabel resultLabel; //shows user input after direction is entered
    private JTextField direction; //allows direction to be entered

    //private JLabel healthLabel, potionsLabel;


    public JTextField getDirection(){
        return direction;
    }

    public TextPanel()
    {
      directionLabel = new JLabel 
            ("Enter n for north, e for east, s for south, and w for west.");
      resultLabel = new JLabel ("---");

      //healthLabel = new JLabel ("Health Points: ");
      //potionsLabel = new JLabel ("Potions Remaining: ");

      direction = new JTextField (5);
      direction.addActionListener (new TempListener());
      add (directionLabel);
      add (direction);
      add (resultLabel);
      //add (healthLabel);
      //add (potionsLabel);

    }


//stores user input for direction
private class TempListener implements ActionListener {

      @Override
      public void actionPerformed (ActionEvent e)
      {
         String directionGiven;
         directionGiven = direction.getText();

         resultLabel.setText ("You moved: " + directionGiven);

        //d.keyPressed(directionGiven);
      }
   }

}
将副本的引用传递给TextPanel

这样,你可以在需要的时候调用地牢的方法。就我个人而言,我更喜欢使用接口,因为它限制了TextPanel的功能,但为了简单起见,这是可行的

您还需要稍微重新构造MazeDriver的构造函数

public class MazeDriver 
{
    public MazeDriver(){  
        Dungeon dungeon = new Dungeon();

        JFrame frame = new JFrame();
        frame.setTitle("Maze Game");
        frame.add(dungeon);
        frame.setLocationRelativeTo(null); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        TextPanel panel = new TextPanel(dungeon);
        panel.setBackground (Color.white);
        panel.setPreferredSize (new Dimension (800, 400));    

        frame.getContentPane().add(panel, BorderLayout.NORTH);
        frame.setVisible(true);
        frame.pack();              
    }               
}

最简单的解决方案是将构造函数中的引用传递给需要调用的对象。例如:

//stores user input for direction
private class TempListener implements ActionListener {

  private MazeDriver driver;
  public TempListner(MazeDriver driver) {
      this.driver = driver;

  @Override
  public void actionPerformed (ActionEvent e)
  {
     String directionGiven;
     directionGiven = direction.getText();

     resultLabel.setText ("You moved: " + directionGiven);

    driver.keyPressed(directionGiven);
  }
}

作为一个通用解决方案,我将为有时称为业务逻辑的逻辑和用户界面创建单独的类。这种分开的职责将使代码更易于理解和维护

在实现gui时,是否仍希望用户在文本字段中键入方向?您只需聆听按键事件,并在按键按n、s、e、w或任何箭头键时做出反应,而无需在字段中实际键入。
//stores user input for direction
private class TempListener implements ActionListener {

  private MazeDriver driver;
  public TempListner(MazeDriver driver) {
      this.driver = driver;

  @Override
  public void actionPerformed (ActionEvent e)
  {
     String directionGiven;
     directionGiven = direction.getText();

     resultLabel.setText ("You moved: " + directionGiven);

    driver.keyPressed(directionGiven);
  }
}