public class DigitalClockApp extends JFrame {
private JLabel clockLabel;
private JButton startButton, stopButton;
// 스레드의 명령의 실행여부 상태를 저장하기 위한 필드
// => false: 스레드로 명령 미실행, true: 스레드로 명령 실행
private boolean isRun;
public DigitalClockApp(String title) {
super(title);
isRun = true;
/*
Date date = new Date();
SimpleDateFormat dateFormatformat = new SimpleDateFormat("yyy년 MM월 dd일 HH시 mm분 ss초");
String printDate = dateFormatformat.format(date);
*/
// 텍스트 가운데 정렬
// clockLabel = new JLabel("2024년 05월 17일 16시 55분 20초", JLabel.CENTER);
// clockLabel = new JLabel(printDate, JLabel.CENTER);
// 새롭게 생성된 스레드를 사용하여 JLabel 컴포넌트의 문자열을 변경 처리
clockLabel = new JLabel("", JLabel.CENTER);
clockLabel.setFont(new Font("굴림체", Font.BOLD,30));
startButton = new JButton("다시 실행");
stopButton = new JButton("일시 중지");
startButton.setFont(new Font("굴림체", Font.BOLD,20));
stopButton.setFont(new Font("굴림체", Font.BOLD,20));
startButton.setEnabled(false); // JButton 컴포넌트 비활성화 처리
JPanel panel = new JPanel();
panel.add(startButton);
panel.add(stopButton);
// Thread 객체로 새로운 스레드를 생성하여 run() 메소드에 명령을 실행 방법 - 1
// new ClockThread().start();
// 익명클래스 가지고 하나의 객체를 만들어 스레드를 생성하여 실행하는 방법 - 2
// 익명클래스로 Runnable 객체를 생성해 Thread 클래스의 생성자 매개변수에 전달하여
// Thread 객체를 생성한 후 start() 메소드를 호출해 새로운 스레드 생성
// => 익명 클래스로 Runnable 객체를 생성하지 않고 람다표현식의 Runnable 객체 생성 가능
new Thread(new Runnable() {
@Override
public void run() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyy년 MM월 dd일 HH시 mm분 ss초");
while(true){
// isRun 필드값이 [true]인 경우에만 플렛폼의 현재 날짜와 시간을 제공받아
// JLabel 컴포넌트의 문자열 변경
if(isRun) {
// Date date = new Date();
// String printDate = dateFormat.format(date);
// JLabel.setText(String label) : JLabel 컴포넌트의 문자열(라벨)을 변경하는 메소드
// clockLabel.setText(printDate);
clockLabel.setText(dateFormat.format(new Date())); // 위에 명령 간소화
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// 람다 표현식으로 실행 방법 - 3
/*new Thread(() -> {
SimpleDateFormat dateFormatformat = new SimpleDateFormat("yyy년 MM월 dd일 HH시 mm분 ss초");
while (true) {
Date date = new Date();
String printDate = dateFormatformat.format(date);
// JLabel.setText(String label): JLabel 컴포넌트의 문자열(라벨)을 변경하는 메소드
clockLabel.setText(printDate);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();*/
getContentPane().add(clockLabel, BorderLayout.CENTER);
getContentPane().add(panel, BorderLayout.SOUTH);
startButton.addActionListener(new ClockButtonEventHandle());
stopButton.addActionListener(new ClockButtonEventHandle());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBounds(700,200,600,200);
setVisible(true);
}
public static void main(String[] args) {
new DigitalClockApp("디지털 시계");
}
/*
// 스레드 클래스를 내부 클래스로 만들거면 Thread 상속 받으면 됨
public class ClockThread extends Thread {
@Override
public void run() {
SimpleDateFormat dateFormatformat = new SimpleDateFormat("yyy년 MM월 dd일 HH시 mm분 ss초");
while(true){
Date date = new Date();
String printDate = dateFormatformat.format(date);
// JLabel.setText(String label): JLabel 컴포넌트의 문자열(라벨)을 변경하는 메소드
clockLabel.setText(printDate);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}*/
// JButton 컴포넌트를 누른 경우에 대한 이벤트 처리 기능을 제공하는 클래스
// => JButton 컴포넌트를 구분하여 isRun 필드값 변경 처리
public class ClockButtonEventHandle implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object eventSource = e.getSource();
if(eventSource == startButton) {
startButton.setEnabled(false);
stopButton.setEnabled(true);
isRun = true;
} else if(eventSource == stopButton) {
startButton.setEnabled(true);
stopButton.setEnabled(false);
isRun = false;
}
}
}
}