본문 바로가기

Swing/Thread Examples

Thread in Swing

Swing  프로그램 내에서 User 쓰레드와 이벤트핸들러 내에서 또 다른 쓰레드를 호출하는 예를 알아본다.

User 쓰레드를 이용하여 원이 이동하는 에니메이션을 구현한 예제

package applet;
import javax.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;

import javax.swing.*;

public class HelloApplet extends JApplet {
 
 static final Point p = new Point();
 
 @Override
 public void init(){
  final Canvas canvas = new MyCanvas();
  add(canvas,"Center");
  
  JButton btn = new JButton("쓰레드 실행");
  add(btn, "North");
  
  btn.addActionListener(new ActionListener() {
   @Override
   public void actionPerformed(ActionEvent e) {
    new Thread(new Runnable() {
     @Override
     public void run() {
      while(true){
       p.x++;
       p.y++;
       canvas.repaint();
       try {
        Thread.sleep(100);
       } catch (InterruptedException e) {
        e.printStackTrace();
       }
      }
     }
    }).start();
   }
  });
 }
 
 // 내부클래스로 선언한 Canvas 클래스
 static class MyCanvas extends Canvas {
  private BufferedImage bi;

  public MyCanvas(){
   setBackground(Color.WHITE);
   bi = new BufferedImage(30, 30, BufferedImage.TYPE_INT_RGB);
   Graphics g = bi.getGraphics();
   g.setColor(Color.WHITE);
   g.fillRect(0,0,bi.getWidth(), bi.getHeight());
   g.setColor(Color.RED);
   g.fillOval(0, 0, 30, 30);
  }
  @Override
  public void paint(Graphics g) {
   g.drawImage(bi,p.x,p.y,null);
  }
 }

}



Swing 에서 Event Dispatching Thread 가 실행하는 코드 내에서 또 다른 쓰레드를 실행하는 예

package applet;
import javax.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;

import javax.swing.*;

public class HelloApplet extends JApplet {
  
 @Override
 public void init(){

  JButton btn = new JButton("JLabel 추가");
  add(btn, "North");
  
  btn.addActionListener(new ActionListener() {
   @Override
   public void actionPerformed(ActionEvent e) {
    JLabel lb = new JLabel("새로 추가된 콤포넌트");
    add(lb, "Center");
    validate();
    /*
    * Event Dispatching Thread 가 실행하는 코드 내에서 쓰레드를 실행할 필요가 있다면 다음과 같이 한다.
    * Swing 콤포넌트들은 Thread-Safe 가 적용되어 있지 않기 때문에 다수개의 쓰레드를 실행할 필요가 있을 때는
    * 순차적으로 실행될 필요가 있고 SwingUtilities.invokeLater()를 이용하면 설정한 쓰레드를 AWT Event Thread의
    * 이벤트 큐에 Runnable 인스턴스를 등록할 수 있으며 이벤트 코드가 모두 실행된 후에 나중에 해당 코드가 실행된다.
    * new Thread(new Runnable() { 처럼 이벤트 내에서도 User 쓰레드를 생성하고 호출할 수도 있지만,
    * Thread -Safe 하지 않은 점을 염두에 두고 순차실행이 필요한 경우라면 아래처럼 해야만 일관성이 유지될 것이다.
    */
    /* 
    SwingUtilities.invokeLater(new Runnable() {
     @Override
     public void run() {
      JLabel lb = new JLabel("새로 추가된 콤포넌트");
      add(lb, "Center");
      validate();
     }
    });*/
   }
  });
 }
}