我正在用 Java 创建一个纸牌游戏。我已经编写了整个游戏逻辑,包括所有规则等,并且我已经开始在该模型之上实现 GUI。
我有 5 个类,但我要讨论的只是“Main”或游戏类和“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。
我的问题是,如何让Play()方法调用GUI类中的方法?当我尝试从 Play() 方法运行 UpdateHand() 时,只需使用
gui.UpdateHand();
它在 gui.UpdateHand() 行返回 NullPointerException,但当我告诉它时,仍然打印 UpdateHand() 方法内的变量以进行控制台,例如 ArrayList。正如我所说,我不想在 gui 上有一个更新棋盘的按钮,而是希望我的 Play() 方法在循环其回合序列时调用 UpdateMethod,然后当玩家需要进行卡牌选择时,而不是使用我现在使用的控制台扫描仪,运行一个方法,该方法向板上添加一个文本字段和一个按钮,供用户输入他们的选择,然后返回到 Play() 方法以继续进行游戏计算.
任何人都可以阐明我做错了什么以及如何实现我在此处指定的目标吗?
编辑:
根据要求提供两个类的更多代码
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(),说它必须是静态的
最佳答案
我认为我们可能需要更多代码来回答这个问题。对我来说,它看起来可能很简单,比如 GUI gui 变量的范围。在您显示的示例中,gui 的范围仅在您创建的 Runnable 对象的 run 方法中。
传统上,在 GUI 中调用某些内容的正确方法是使用 Singleton pattern 。基本上,你可以调用
GUI.getInstance().myMethod();
此外,稍微切题一下,如果这是 UpdateHand() 方法中的唯一代码,那么额外的线程就是浪费时间,因为
SwingUtilities.invokeLater(new Runnable(){ ... });
只需将 Runnable 放入事件队列中,等待轮到运行。因此,如果这是您的方法中唯一的事情,那么线程几乎会立即消失。尽管它可能不是其中唯一的代码,因为您没有结束括号,只是想我会注意到它。
最后,任何影响 GUI 的事情 ( except some things... ) 都需要在 invokeLater 中完成。否则,您可能会遇到让您抓狂的错误,因为它似乎不在您的代码中。
关于java - 从单独的类方法运行 GUI 更新方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10050866/