gpt4 book ai didi

Java Swing Action 执行

转载 作者:行者123 更新时间:2023-12-01 12:25:11 25 4
gpt4 key购买 nike

您好,我正在一个项目中工作,我必须创建一个 CUI 游戏,现在将其转换为 GUI,我正在向与游戏交互的按钮添加功能,但遇到了麻烦。

这是我尝试访问的方法。它属于一个名为 Pet 的类。

public double feedPet() {

if(this.hunger < MAX_HUNGER) {
this.hunger += food;
if(this.hunger > MAX_HUNGER) {
this.hunger = MAX_HUNGER;
}
System.out.println(this.petName + " enjoyed the meal!");
System.out.println("Hunger increased by " + food + " to a total of " + this.hunger);
spacing();
}
else {
System.out.println(this.petName + " is currently full!");
spacing();
}

return this.hunger;
}

这是尝试访问该方法的类。

public GamePanel(PetWorld petWorld, Pet pet, Game game) {
initComponents();
genComponents(pet);
}

private void genComponents(final Pet pet) {


this.setSize(600, 600);

graphicsPanel.setSize(600, 400);
graphicsPanel.setBackground(Color.red);

buttonPanel.setSize(600, 200);

buttonPanel.setBorder(BorderFactory.createTitledBorder("Pet Options"));

JButton feedBtn = new JButton("Feed");
JButton playBtn = new JButton("Play");
JButton sickBtn = new JButton("Medicine");
JButton trainBtn = new JButton("Train");
JButton sleepBtn = new JButton("Sleep");

//// error occurring here I believe \\\\
feedBtn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
pet.feedPet();
}
});

buttonPanel.setLayout(new GridBagLayout());

GridBagConstraints gc = new GridBagConstraints();

//// Pet Options \\\\
gc.weightx = 0.5;
gc.weighty = 0.5;

gc.gridx = 0;
gc.gridy = 1;
buttonPanel.add(feedBtn, gc);

gc.gridx = 1;
gc.gridy = 1;
buttonPanel.add(playBtn, gc);

gc.gridx = 2;
gc.gridy = 1;
buttonPanel.add(sickBtn, gc);

gc.gridx = 3;
gc.gridy = 1;
buttonPanel.add(trainBtn, gc);

gc.gridx = 4;
gc.gridy = 1;
buttonPanel.add(sleepBtn, gc);

}

我必须把宠物做成最终的,我相信这很糟糕,因为我改变了宠物本身的值(value)观,例如幸福,饥饿等

按下按钮时出现的错误

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at pdcmainGUI.GamePanel$1.actionPerformed(GamePanel.java:63)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

有更好的方法来实现我想要做的事情吗?我猜这是由于尝试更改变量值但在 gui 类中设置为 Final 的方法引起的?任何建议表示赞赏。

最佳答案

问题与您对 Action 监听器的声明有关。当您在 genComponents(final Pet pet) 过程中创建 ActionListener() 时,这不是它在运行时执行的位置。

但首先,我们还需要明确将变量调用为 final。这意味着 pet 无法重新分配给不同的 pet,但这并不意味着您无法访问 pet 的方法可能会改变,例如 isHungry()、setFed(boolean) 等。

第二,让你的宠物进入范围。当您定义genComponents(final Pet pet)过程时,pet在作用域内,因此java编译器在编译时不会出现问题。但在运行时,genComponents(final Pet pet) 过程会在 pet 已知的情况下执行,并在此执行期间创建 ActionListener,指向参数的变量位置。 genComponents(...) 过程完成后,参数超出范围。当按下按钮触发 ActionListener 时,它会尝试引用超出范围的变量的内存位置。

private void genComponents(final Pet pet) {

....

feedBtn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
pet.feedPet(); <-- pet refers to the parameter, but it is out of scope when this gets executed.
}
});

....
}

解决方案空间:要解决此问题,需要从范围内的某个位置访问 pet,您只需将 pet 存储为私有(private)类变量即可做到这一点.

public class GamePanel {

private final Pet pet;

public GamePanel(PetWorld petWorld, Pet pet, Game game) {
this.pet = pet;
initComponents();
genComponents(); <-- remove the pet parameter
}

private void genComponents() {
....

feedBtn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
pet.feedPet(); <-- this pet now refers to the class variable, which is still in scope.
}
});

....
}
}

关于Java Swing Action 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26416180/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com