Java Swing:从单独的Class方法运行GUI Update方法

时间:2012-04-07 01:10:50

标签: java swing user-interface

好的,我正在用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(),说它必须是静态的

1 个答案:

答案 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中完成。否则,您最终可能会遇到错误,这些错误会让您发疯,因为它似乎不在您的代码中。