`

Java GUI在循环中调用repaint的问题分析

阅读更多
在Java中,循环调用repaint()来显示动画效果,是个很自然的方法,
然而这是不可行的。其实Java有一个GUI (AWT) Thread来负责GUI
事件的分发,这个线程接受输入事件,放入事件队列,从该队列
中拿出一个事件分发出去。而这个线程事实上与GUI component
线程[一般是你应用程序的主线程]是绑定的。也就是说如果当前
的线程休眠,事件分发的线程同样会休眠。试想如果如果不这么
做,事件被分发,而当前线程正在休眠,事件就得不到响应,那么
这个事件就会丢失。
下面看看昨天遇到的一个问题:
昨天gyk同学问我一个动画不能显示,而是立即出来最终的画面,
他就使用循环调用repaint()的方法来显示动画效果:
while(condition){
 //修改动画的数据
 repaint();
}

然而这是不可行的,实际上多个连续的repaint会合并成一个。这样
只用最后一个repaint()会导致update()和paint()被调用。
如果试图休眠一段时间来隔开多个repaint()操作,从而避免多个连续
的repaint()被合并的问题:
while(condition){
 //...修改动画的数据
 try { 
     Thread.sleep(100); 
  } catch(InterruptedException ex) {} 
 repaint();
}

事实上是不行的,正像上面我们说的:当前线程sleep,GUI事件分发线程同
样也会sleep,这样这些分发事件事实上被冻结而积累在队列中,同样连续的
多个repaint事件仍然会被合并成一个repaint.
许多时候或许我们简单的认为repaint之会立即调用update和paint,正如我
们上面所说的它只是产生一个事件,然后立即返回,实际上是个异步的操作
过程。
那最终怎么改才行呢?
其实可以用一个专门的线程来做这件事。事实如果你不是刚开始写GUI程序的话,
首先就应该想到用这种方法的,这样才能构建出灵敏的界面。难道你让动画放着
而界面的其他事件得不到响应么?例如按钮不好用。
把上面的代码放在线程类中的run方法,你一点开始播放按钮,就开启这个线程:
public void run(){
  while(condition){
   //...修改动画的数据
   try { 
          Thread.sleep(100); 
       } catch(InterruptedException ex) {
       } 
       repaint();
  }
}

分享到:
评论

相关推荐

    java GUI小游戏之小鼠快跑

    在Java编程世界中,GUI(图形用户界面)游戏开发是一项有趣的实践,能够帮助开发者更好地理解和运用Java的Swing或JavaFX库。"小鼠快跑"是一个典型的GUI小游戏,它通常包含一个简单的游戏场景,玩家控制的角色(如...

    狂神说_Java_GUI编程-贪食蛇素材.7z

    在Java中,我们可以利用`repaint()`方法来触发重绘,`paintComponent(Graphics g)`方法用于自定义绘制。同时,为了实现游戏循环,我们需要一个定时器来定期调用这些方法。 通过实践这个项目,开发者不仅可以掌握...

    Java版飞机游戏

    【Java版飞机游戏】是一款基于Java编程语言开发的娱乐项目,它展示了Java在游戏开发中的应用,同时也为学习Java的开发者提供了实践平台。通过分析和理解这个游戏的源代码,我们可以深入学习Java图形界面(GUI)设计...

    简单的java applet图像移动重画实例

    - 通过在一个循环中连续调用`repaint()`并更新图像位置,可以创建动画效果。 - 可能使用`Thread.sleep()`方法来控制帧率,避免过度绘制导致的性能问题。 7. **代码示例**: ```java import java.applet.Applet;...

    java窗体内的弹性小球

    在Java编程语言中,"java窗体内的弹性小球"是一个常见的初级到中级的实践项目,它涉及到图形用户界面(GUI)的创建、事件处理以及简单的物理模拟。这个项目的目标是设计一个应用程序,其中一个小球在窗口内自由移动...

    课程设计-基于Java swing带GUI界面的俄罗斯方块游戏.zip

    我们使用Swing的paintComponent方法绘制游戏板,每次方块下落时调用repaint()刷新界面。 3. **方块逻辑**:方块由多个单元格组成,它们以预定义的形状出现。我们需要一个类来表示方块,包含其形状、旋转状态和位置...

    java applet 连续画同心圆

    4. **动画效果**:为了实现圆连续变小的动画效果,我们需要在Applet的主循环中调用`repaint()`方法,这会触发`paint()`方法的重绘。可以使用`Thread.sleep()`来控制绘制的频率,从而实现平滑的动画过渡。 5. **用户...

    飞机大战Java版javaSwing

    为了实现动画效果,通常会在游戏主循环中定期调用repaint()方法,使得界面不断刷新,呈现出动态的画面。 四、事件处理 Java Swing提供了丰富的事件处理机制,包括动作事件、键盘事件、鼠标事件等。在"飞机大战"中...

    java鼠标瞄准炮台打鸟游戏

    例如,使用javax.swing.Timer来定时更新和重绘游戏画面,而不是在主循环中频繁调用repaint()。 总的来说,“java鼠标瞄准炮台打鸟游戏”是一个融合了Java基础语法、GUI编程、事件处理和面向对象设计的综合实践项目...

    Java实现黑客帝国代码雨

    在`RainCanvas`中,我们需要重写`paint`方法,这是Java GUI组件进行绘制的核心方法。在`paint`方法内,我们创建一系列虚拟的“字符”,模拟代码字符,并让它们沿着屏幕垂直下落。 1. **初始化画布**:首先,我们...

    java小球碰撞边框反弹并且互相碰撞消失

    8. **绘图与重绘**:在Java中,我们通常使用`repaint()`方法来触发组件的重新绘制。每当小球位置改变或者有新的碰撞发生,都需要调用此方法,让GUI刷新显示。 9. **时间管理**:游戏的节奏往往需要定时器控制。`...

    java时钟定时器,便捷式时钟程序,实现了时钟的控制面板

    在这个例子中,`actionPerformed` 方法被用来在每秒钟更新一次时钟的显示,通过调用 `repaint()` 方法触发界面重绘。 3. **Timer 类**: `javax.swing.Timer` 类是一个非常有用的工具,用于定期执行任务。在这个时钟...

    Idea编写的简易Java雷霆战机源码

    例如,开发者可能创建了一个单独的线程来处理游戏循环,每帧更新游戏状态,并调用repaint()方法刷新界面,从而实现了动态画面。 此外,游戏中的图片资源管理也是一大重点。在"lightning"这个文件夹中,包含了游戏的...

    java贪吃蛇代码

    在本项目中,我们利用Java来开发一款经典的贪吃蛇游戏,它不仅展示了Java的基本语法,还涉及图形用户界面(GUI)的设计以及事件处理机制。以下是关于这个项目的详细知识点: 1. **Java基础** - 类与对象:贪吃蛇...

    java applet小程序

    这个程序展示了Java在图形用户界面(GUI)开发中的能力,特别是对于实时动画和交互性。 首先,我们需要理解Java Applet的基本结构。一个Java Applet通常包含`<applet>`标签在HTML中定义,以及一个继承自`java....

    Java使文字垂直伸展变形.rar

    在Java编程语言中,创建文字垂直伸展变形的动画效果是一项有趣的挑战,它涉及到图形用户界面(GUI)设计和时间序列动画的实现。这个压缩包文件"Java使文字垂直伸展变形.rar"很可能包含了实现这一效果的源代码,其中...

    java版坦克大战

    这通常在`while`或`do-while`循环中完成,每帧都会调用`repaint()`方法来刷新画面,并更新所有对象的状态。在Java中,`Thread.sleep()`函数可以用来控制游戏的帧率,提供流畅的动画效果。 地图是游戏中的关键部分,...

    全国计算机等级考试二级Java真题及答案.pdf

    例如,第11题中出现的A、B、C、D分别对应着Java中不同的方法,分别是paint()、setSize()、getSize()、repaint(),它们都是Component类中的方法,用于画图和控制组件大小。 文档中还提到了对数组的操作,如“int[] ...

    java旋转陀螺

    在事件处理方法中,我们可以更新旋转角度并调用组件的`repaint()`方法,请求GUI重新绘制。 5. **坐标系统与变换**:理解Java的坐标系统至关重要,原点通常位于组件的左上角。在进行旋转时,我们需要确保知道图像的...

    Java文字效果.pdf

    - `run()`:循环调用`repaint()`方法,改变字体颜色并重新绘制Applet。 - `paint()`:设置字体样式和颜色,调用`drawString()`方法绘制中文字符串。 #### 7. HTML集成与编译运行 - **HTML文件**:使用`<applet>`...

Global site tag (gtag.js) - Google Analytics