为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

动漫人物 2022-12-21 10:41:46
我正在使用 Swing 和 Firebase 编写基于 Java 的游戏。我将所有玩家存储在一个列表中,当他们中的任何一个移动时,onChildChanged(...)回调(见下文)被触发。由于这是异步的,我显然不能设置任何超出函数范围的变量。这一切都很好,直到我需要将这个播放器实际绘制到屏幕上。因为我扩展了 aJPanel并覆盖了它,所以paintComponent(Graphics g)我必须在这个方法中完成我的所有绘图(或者至少这是我被告知的)。问题是我需要从回调内部绘制这个玩家,这是我不知道该怎么做的。我试图将Graphics g对象“导出”到全局变量,然后在异步函数中使用该变量,但这没有产生任何结果。也许是因为它实际上并没有绘制到 JPanel 的画布上?所以我有一个像这样的类:class Screen extends JPanel {@Overridepublic 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()方法中绘制播放器,我想知道如何做到这一点。谢谢!
查看完整描述

1 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

除了在 paintComponent 方法内,你不应该在任何地方绘画。所以解决方案是:

  • 更新用于告诉 GUI 要绘制什么的模型字段。

  • 如果此更新将以任何其他方式直接影响 GUI,例如更新文本字段、标签、JTables 等,则应在 EDT 上执行此数据更改,方法是将其放入传入的 Runnable 中的事件队列中SwingUtilities.invokeLater(...)

  • 然后打电话repaint()

  • 然后 GUI 将使用这些字段并在 Swing 事件线程上完成所有绘制。

请注意,这repaint()是少数可以从 EDT 调用的 Swing 方法之一


虽然哈哈,但我对更新模型字段的意思有点困惑,你能澄清一下吗?

如果您正在创建任何复杂的 GUI,您可能会使用模型 - 视图类型的结构(例如模型 - 视图 - 控制器的 MVC),其中将程序逻辑(模型部分)与 GUI(视图)分开。视图描述了模型的状态并允许用户交互,所以我说的是状态字段。

例如,如果你有一个带有动画的游戏,模型将代表玩家的位置、玩家的状态(生命值、武器、库存)、他们的行为……而视图将绘制所有这些基于关于模型的状态。


查看完整回答
反对 回复 2022-12-21
  • 1 回答
  • 0 关注
  • 45 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信