好的,我正在用Java创建一个扑克牌游戏。让我首先说我已经编写了整个游戏逻辑,包括所有规则等,我已经开始在该模型之上实现GUI。我对Java和Swing的了解至多是基本的,所以我没有。
我有5个课程,但我将要讨论的课程只是'主'或游戏类和'GUI'课程。首先,为了构造手,我使用对象类型的数组列表<卡>我创造了。该游戏通过播放方法'Play()'和(此时)通过控制台向他显示人类玩家手并要求他在ArrayList中进行整数选择来放置。我在Main类中有main(String [] args),为了调用类GUI并设置我使用的游戏板。
public static void main(String[] args)
{
Deck deck = new Deck();
ai = new AI;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI();
gui.setVisible(true);
}
})
理想情况下,我希望通过使用Play()方法来玩游戏,并从GUI类调用方法来更新棋盘并返回人类玩家选择的卡片。目前,我能做的最好的事情是,在设置电路板时,我通过
实现了一个按钮 Button go = new Button("Update Hand");
ButtonDisplay.add(go);
go.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Thread queryThread = new Thread() {
public void run() {
UpdateHand();
}
};
queryThread.start();
}
});
然后运行
public void UpdateHand()
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
inPlay = main.inPlay;
UpdateInPlay(inPlay, InPlayDisplay);
HumanHand = main.humanplayer;
HumanHandDisplay.removeAll();
单击时,将清除面板并重新刷新卡JLabels。
我的问题是,如何在GUI类中调用Play()方法?当我尝试从Play()方法运行UpdateHand()时,只需使用
gui.UpdateHand();
它在那个gui.UpdateHand()行返回一个NullPointerException,但是当我告诉它时,仍然会将UpdateHand()方法中的变量打印到控制台,例如ArrayList。正如我所说的,我希望我的Play()方法只需调用UpdateMethod就可以调整UpdateMethod,因为它循环转动它的顺序,然后当玩家需要进行卡片选择时,使用我现在使用的控制台扫描程序,运行一个方法,向用户输入文本字段和按钮给用户输入他们的选择,然后返回到Play()方法继续进行游戏计算
任何人都可以了解我做错了什么,以及如何实现我在这里指定的内容?
编辑:
我要求的2个类的更多代码
GUI
public class GUI extends JFrame
{
public Main main;
private ArrayList<Card> AIHand;
public GUI() {
pane = this.getContentPane();
pane.setLayout(new GridLayout(6,1,2,2));
AIBackDisplay = new JPanel();
//just more of the same for other panels here
pane.setBackground(Color.GREEN);
setTitle("Last Man Standing");
pane.add(AIBackDisplay);
pane.add(AIHandDisplay);
pane.add(InPlayDisplay);
pane.add(HumanHandDisplay);
pane.add(HumanBackDisplay);
pane.add(HumanFacedownDisplay);
pane.add(ButtonDisplay);
setSize(800, 700);
setLocationRelativeTo(pane);
setDefaultCloseOperation(EXIT_ON_CLOSE);
UpdateFacedown(AIFacedown, AIBackDisplay); //these are methods called for original display
UpdateFacedown(HumanFacedown, HumanBackDisplay);
然后我有updateHand()方法,它通过按钮调用并执行此操作
for (int i = 0; i < (HumanHand.size()); i++)
{
Card card = HumanHand.get(i);
BufferedImage cardImage = null;
try {
cardImage = ImageIO.read(new File("card/" + card + ".jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JLabel picLabel = new JLabel(new ImageIcon( cardImage ));
HumanHandDisplay.add(picLabel);
}
HumanHandDisplay.updateUI();
我的主课有
public class Main {
static AI ai;
public static GUI gui;
发现GUI必须是静态的,否则我无法使用
调用它 Scanner sc = new Scanner (System.in);
choice = sc.nextInt(); //what i'm using now
//choice = gui.GUIReturn(); //what i'd like to use
即使GUI是静态的,也不会因为某种原因让我运行gui.GUIReturn(),说它必须是静态的
答案 0 :(得分:2)
我认为我们可能需要更多代码才能回答这个问题。对我来说,看起来它可能像GUI gui变量的范围一样简单。在您显示的示例中,gui的范围仅在您创建的Runnable对象的run方法中。
传统上,在GUI中调用某些内容的正确方法是使用Singleton pattern。基本上,那就是你打电话了
GUI.getInstance().myMethod();
另外,如果这是你的UpdateHand()方法中唯一的代码,那么你的额外线程是浪费时间,因为
SwingUtilities.invokeLater(new Runnable(){ ... });
只需将Runnable放入事件队列中,等待轮到它运行。因此,如果这是你方法中唯一的东西,那么线程就会立即消失。虽然它可能不是那里唯一的代码,因为你没有结束括号,只是想我会注意到它。
最后,影响GUI的ANYTHING(except some things...)需要在invokeLater中完成。否则,您最终可能会遇到错误,这些错误会让您发疯,因为它似乎不在您的代码中。