Java Swing:运行GUI从单独的类方法更新方法

问题描述:

好吧,我正在用Java创建一个纸牌游戏。让我开始说我已经编写了整个游戏逻辑,包括所有的规则等,并且我已经开始在该模型之上实现GUI。我对Java和Swing的了解基本上与我一样纯粹。Java Swing:运行GUI从单独的类方法更新方法

我有5个班,但我会谈论的只是'主要'或游戏类和'图形用户界面'类。首先,为了构建手,我使用了我创建的对象类型< Card>的ArrayLists。游戏通过玩'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); 
      } 
     }) 

我非常希望游戏通过使用播放()方法和调用方法从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(); 

,从而清除面板和重绘卡的JLabel背部的按钮上。

我的问题是,我该如何在GUI类中制作Play()方法调用方法?当我尝试从Play()方法运行UpdateHand()时,只需使用

gui.UpdateHand();

它返回一个NullPointerException在那个gui.UpdateHand()行,但仍然打印UpdateHand()方法内的变量到控制台,当我告诉它,如ArrayList。正如我所说的,与其在gui上更新棋盘上的按钮不同,我希望我的Play()方法在循环其顺序时调用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()出于某种原因,说它必须是静态的

+1

构建一个[sscce](http://sscce.org/)可能是一个有用的练习。 – trashgod 2012-04-07 03:49:58

+0

请学习java命名约定并坚持使用它们。 – kleopatra 2012-04-07 09:11:19

我想我们可能需要更多的代码来回答这个问题。对我来说,它看起来可能像GUI gui变量的范围那样简单。在你展示的例子中,gui的作用域只在你创建的Runnable对象的run方法中。

传统上,在GUI中调用某些东西的正确方法是使用Singleton pattern。基本上,它可以让你叫

GUI.getInstance().myMethod(); 

此外,在一个轻微的切线,如果这是你的UpdateHand()方法的唯一代码,您额外的线程是在浪费时间,因为

SwingUtilities.invokeLater(new Runnable(){ ... }); 

简单将Runnable放入事件队列中,等待轮到它运行。所以如果这是你方法中唯一的东西,那么线程就会立即消失。虽然它可能不是那里唯一的代码,因为你没有结束括号,只是想我会记下它。

最后,影响GUI的ANYING(except some things...)需要在invokeLater中完成。否则,最终会出现错误,这会使你发疯,因为它看起来不在你的代码中。

+0

好的帖子已更新。如果我把 SwingUtilities.invokeLater(Runnable的新(){ \t \t \t \t \t \t公共无效的run(){ \t \t \t \t \t选择= gui.GUIReturn(); \t \t \t \t \t \t}} ); 它给了我一个错误,说int必须是最终的,但其他地方没有我有int选择使用可以使用它。 – Sean 2012-04-07 02:20:19

+0

现在已经实现了Singleton,它工作正常。感谢您的帮助 – Sean 2012-04-07 14:04:41