[ 작업 환경 ]
Windows10
jdk-15
[ 문제 ]
< 한국어 >
• 첨부로 제공된 AniTimerApp.java_part을 참고하고, 다음의 조건을 만족시키도록 프로그램을 완성하시오
1. Play 버튼을 누르면 jlabel1에는 1초 간격으로 숫자가 1씩 증가되어 보이도록 하고, jlabel2 에는 3.5초 간격으로 숫자가 1씩 증가되어 보이도록 한다.
2. Pause 버튼을 누르면 jlabel1과 jlabel2에 숫자가 증가되지 않고 멈추어 있고, Play 버튼을 누르면 기존 숫자에 이어서 다시, 각각 1초와 3.5초 마다, 1씩 증가되도록 한다.
• Thread를 사용하여 구현하시오.
< 영어 >
• Refer to the attached AniTimerApp.java_part and complete the program to meet the following conditions:
1. Press the Play button to make jlabel 1 appear increasing by 1 every 1 second, and jlabel 2 appear increasing by 1 every 3.5 second.
2. Press the Pause button to stop jlabel1 and jlabel2 without increasing the number, and press the Play button to increase the number by 1 every 1 and 3.5 seconds, respectively.
•Implement using Thread.
// AniTimerApp.java_part
import javax.swing.Timer;
public class AniTimerApp extends javax.swing.JFrame {
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JLabel jlabel1;
private javax.swing.JLabel jlabel2;
// End of variables declaration
public AniTimerApp() {
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jPanel3 = new javax.swing.JPanel();
jlabel1 = new javax.swing.JLabel("Test1");
jlabel2 = new javax.swing.JLabel("Test2");
java.awt.FlowLayout jPanel3Layout = new java.awt.FlowLayout(java.awt.FlowLayout.CENTER);
jPanel3.setLayout(jPanel3Layout);
jPanel3.add(jlabel1);
jPanel3.add(jlabel2);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Play");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jButton2.setText("Pause");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jButton1, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jButton2, javax.swing.GroupLayout.Alignment.TRAILING))
.addContainerGap())
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton2)
.addContainerGap(237, Short.MAX_VALUE))
);
getContentPane().add(jPanel1, java.awt.BorderLayout.LINE_END);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 319, Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);
getContentPane().add(jPanel3, java.awt.BorderLayout.SOUTH);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// PLAY BUTTON
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
}
public static void Hi(){
System.out.println("Hi guys");
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AniTimerApp().setVisible(true);
}
});
}
}
1. AniTimerApp.java 작성 (sample)
아래 소스 코드의 경우, start 버튼 이후 잘 작동하지만, stop 하면 t1이 wait 상태가 되면서 프로그램이 에러 출력 없이 멈춰버리는 문제가 있다. 그래서 그 아래에 wait를 사용하지 않는 소스코드를 2번 항목에 제시하겠다. 그러나 이 소스코드는 정확하게 쓰레드가 잘 돌아간다고 보기 어려워 참고용으로만 봐주자.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.LayoutStyle;
import javax.swing.WindowConstants;
public class AniTimerApp extends JFrame {
// Variables declaration - do not modify
private JButton jButton1;
private JButton jButton2;
private JPanel jPanel1;
private JPanel jPanel2;
private JPanel jPanel3;
private JLabel jlabel1;
private JLabel jlabel2;
int label1Counter = 0;
int label2Counter = 0;
Thread1 t1 = null;
Thread2 t2 = null;
// End of variables declaration
public AniTimerApp() {
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new JPanel();
jButton1 = new JButton();
jButton2 = new JButton();
jPanel2 = new JPanel();
jPanel3 = new JPanel();
jlabel1 = new JLabel("Test1");
jlabel2 = new JLabel("Test2");
FlowLayout jPanel3Layout = new FlowLayout(FlowLayout.CENTER);
jPanel3.setLayout(jPanel3Layout);
jPanel3.add(jlabel1);
jPanel3.add(jlabel2);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Play");
jButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jButton2.setText("Pause");
jButton2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(jButton1, GroupLayout.Alignment.TRAILING)
.addComponent(jButton2, GroupLayout.Alignment.TRAILING))
.addContainerGap()));
jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addComponent(jButton1)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(jButton2)
.addContainerGap(237, Short.MAX_VALUE)));
getContentPane().add(jPanel1, BorderLayout.LINE_END);
GroupLayout jPanel2Layout = new GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGap(0, 319, Short.MAX_VALUE));
jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE));
getContentPane().add(jPanel2, BorderLayout.CENTER);
getContentPane().add(jPanel3, BorderLayout.SOUTH);
pack();
}
private void jButton1ActionPerformed(ActionEvent evt) {
if (t1 == null && t2 == null) {
t1 = new Thread1(jlabel1);
t1.start();
t2 = new Thread2(jlabel2);
t2.start();
} else {
synchronized (t1) {
t1.notify();
}
synchronized (t2) {
t2.notify();
}
}
t1 = new Thread1(jlabel1);
t1.start();
t2 = new Thread2(jlabel2);
t2.start();
}
private void jButton2ActionPerformed(ActionEvent evt) {
try {
synchronized (t1) {
t1.wait();
}
synchronized (t2) {
t2.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void Hi() {
System.out.println("Hi guys");
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new AniTimerApp().setVisible(true);
}
});
}
}
class Thread1 extends Thread {
JLabel label;
public Thread1(JLabel label) {
this.label = label;
}
public void run() {
try {
int i=1;
while (true) {
Thread.sleep(1000);
label.setText(String.valueOf(i++));
}
} catch (InterruptedException e) {
System.out.println(" interrupted");
}
}
}
class Thread2 extends Thread {
JLabel label;
public Thread2(JLabel label) {
this.label = label;
}
public void run() {
try {
int i=1;
while (true) {
Thread.sleep(3500);
label.setText(String.valueOf(i++));
}
} catch (InterruptedException e) {
System.out.println(" interrupted");
}
}
}
2. AniTimerApp.java 작성
// AniTimerApp.java
public class AniTimerApp extends javax.swing.JFrame {
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JLabel jlabel1;
private javax.swing.JLabel jlabel2;
private java.lang.Thread thread1;
private java.lang.Thread thread2;
private boolean isRunning = false;
// End of variables declaration
public AniTimerApp() {
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jPanel3 = new javax.swing.JPanel();
jlabel1 = new javax.swing.JLabel("Test1");
jlabel2 = new javax.swing.JLabel("Test2");
java.awt.FlowLayout jPanel3Layout = new java.awt.FlowLayout(java.awt.FlowLayout.CENTER);
jPanel3.setLayout(jPanel3Layout);
jPanel3.add(jlabel1);
jPanel3.add(jlabel2);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Play");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jButton2.setText("Pause");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jButton1, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jButton2, javax.swing.GroupLayout.Alignment.TRAILING))
.addContainerGap())
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton2)
.addContainerGap(237, Short.MAX_VALUE))
);
getContentPane().add(jPanel1, java.awt.BorderLayout.LINE_END);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 319, Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);
getContentPane().add(jPanel3, java.awt.BorderLayout.SOUTH);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// PLAY BUTTON
isRunning = true;
if (thread1 == null)
{
thread1 = new Thread( new Runnable() {
int val = 1;
public void run()
{
while( true ) {
try
{
Thread.currentThread().sleep(1000);
if (isRunning)
{
jlabel1.setText( ""+ val);
val++;
}
}
catch (InterruptedException ex)
{
}
}
}
}
);
thread1.start();
}
if (thread2 == null)
{
thread2 = new Thread( new Runnable() {
int val = 1;
public void run()
{
while( true ) {
try
{
Thread.currentThread().sleep(3500);
if (isRunning)
{
jlabel2.setText( ""+ val);
val++;
}
}
catch (InterruptedException ex)
{
}
}
}
}
);
thread2.start();
}
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
System.out.println("Pause");
isRunning = false;
}
public static void Hi(){
System.out.println("Hi guys");
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AniTimerApp().setVisible(true);
}
});
}
}