Java 类层次结构使JTextField输入启动方法调用
我和我的团队在我们选择的项目主题上有一些问题。在编辑我们的程序时,我弄得有点乱,我们不确定各个类应该如何准确地按照最佳实践相互交流,或者看到我们想要的输出 我们目前的问题是,尝试从JTextField输入n、w、s、e表示方向,然后作为keyPressed方法的参数,该方法采用字符串,然后调用适当的move方法,对数组/迷宫的行和列采用int值,并在迷宫中移动字符方块。我们希望TextPanel类中来自direction JTextField对象的输入作为两个keyPressed方法的参数,其中它将采用字符串n、w、s、e;然后理想地 最初,我们将所有逻辑都放在一个类中,而没有GUI,这将允许我们穿越迷宫,因此问题在于我们的GUI知识以及如何正确地增加编程以进行测试 认识到这是一个相当模糊的问题,但希望了解如何更好地组织这个程序,让JTextField输入调用其他两个方法 示例代码:Java 类层次结构使JTextField输入启动方法调用,java,swing,Java,Swing,我和我的团队在我们选择的项目主题上有一些问题。在编辑我们的程序时,我弄得有点乱,我们不确定各个类应该如何准确地按照最佳实践相互交流,或者看到我们想要的输出 我们目前的问题是,尝试从JTextField输入n、w、s、e表示方向,然后作为keyPressed方法的参数,该方法采用字符串,然后调用适当的move方法,对数组/迷宫的行和列采用int值,并在迷宫中移动字符方块。我们希望TextPanel类中来自direction JTextField对象的输入作为两个keyPressed方法的参数,其中
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);
}
}