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

时间:2015-03-26 20:59:26

标签: java swing

我的小组和我在选择的项目主题上遇到了一些问题。在编辑我们的程序时,我做了一些混乱,我们不确定类应该如何在最佳实践或看到我们想要的输出方面完全相互通信。

我们目前的问题是尝试从JTextField(n,w,s,e作为方向)输入,然后作为ke​​yPressed方法的参数(接受一个字符串),然后调用适当的移动方法(获取数组/迷宫的行和列的int值)并在迷宫中移动字符方块。我们喜欢方向的输入(TextPanel类中的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);
      }
   }

}

2 个答案:

答案 0 :(得分:0)

Dungeon的引用传递给TextPanel

public class TextPanel extends JPanel {

    private Dungeon d;
    //...    
    public TextPanel(Dungeon d)
    {
        this.d = d;

这样,您可以在需要时调用Dungeon的方法。就个人而言,我更喜欢使用interface,因为它完全限制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();              
    }               
}

答案 1 :(得分:0)

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

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

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