java - 有没有办法从异步方法绘制到 JPanel 上?

标签 java swing firebase awt

我正在使用 Swing 和 Firebase 编写一个基于 Java 的游戏。我将所有玩家存储在一个列表中,当其中任何一个玩家移动时,就会触发 onChildChanged(...) 回调(见下文)。由于这是异步的,我显然无法设置任何超出函数范围的变量。这一切都很好,直到我需要将这个播放器实际绘制到屏幕上。

由于我扩展了 JPanel 并覆盖了它的 paintComponent(Graphics g) 我必须在这个方法中完成所有绘图(或者至少这就是我所做的)告诉)。问题是我需要从回调内部绘制这个玩家,而这是我不知道该怎么做。

我尝试将 Graphics g 对象“导出”到全局变量,然后在异步函数中使用该变量,但这没有产生任何结果。也许是因为它实际上并未绘制到 JPanel 的 Canvas 上?

所以我有一个类似这样的类(class):

class Screen extends JPanel {

@Override
public void paintComponent(Graphics g) {
    // All my painting stuff goes here
}

ref.addChildEventListener(new ChildEventListener() {

            // This is the callback
            @Override
            public void onChildChanged(DataSnapshot snapshot, String previousChildName) {
                      // Draw the player
                }
            }
        });

}

编辑:忘记提及,我还在每个游戏滴答声上调用 repaint() (每秒 60 次)。我不知道这是否会改变任何东西,但以防万一:)

所以我希望能够在回调中绘制播放器或在 paintComponent() 方法中绘制它,我想知道如何做到这一点。

谢谢!

最佳答案

除了在paintComponent方法中之外,你不应该在任何地方进行绘制。所以解决办法是:

  • 更新用于告诉 GUI 要绘制什么的模型字段。
  • 如果此更新将以任何其他方式直接影响 GUI,例如更新文本字段、标签、JTable 等,则应在 EDT 上执行此数据更改,方法是将其放入传递给的 Runnable 内的事件队列中SwingUtilities.invokeLater(...)
  • 然后调用repaint()
  • 然后 GUI 将使用这些字段并在 Swing 事件线程上进行所有绘制。

请注意,repaint() 是少数可以在 EDT 中off调用的 Swing 方法之一。

<小时/>

I am little confused as to what you mean by updating the model's fields though haha, could you maybe clarify that?

如果您正在创建任何复杂的 GUI,您可能会使用模型 - View 类型的结构(例如用于模型- View - Controller 的 M-V-C),其中将程序逻辑、模型部分与 GUI、看法。该 View 描述了模型的状态并允许用户交互,所以我说的是状态字段。

例如,如果您有一个带有动画的游戏,模型将表示玩家的位置、玩家的状态(生命值、武器、股票)、他们的行为,...而 View 将绘制所有内容这基于模型的状态。

关于java - 有没有办法从异步方法绘制到 JPanel 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56351455/

相关文章:

java - 调用函数无法返回或打印

java - 是否可以从java中的另一个类导入监听器

java - Swing 拖放

java - JButton 不工作

android - 如何跟踪在 Firebase 中卸载应用程序的用户的事件

java - 将十进制数转换为大写字母的十六进制数

java - 如何从标准输入非阻塞读取?

ios - 如何为 Firebase Firestore 创建 DocumentSnapshots 以进行测试?

java - 通过 JNI 在 C 和 Java 之间来回调用

javascript - Firebase云函数在完成foreach之前完成