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();
}
});*/
}
});
}
}