0
다시 시도해주세요! 다음 코드에서는 버튼을 눌러 타이머 스레드를 밀고 레이블에 타이핑하여 시작하려고합니다. 버튼을 누를 때마다 새 스레드가 시작되고 각 레이블에이를 표시해야합니다. 그러나 유감스럽게도 각 라벨마다 동일한 타이머가 기록됩니다. 우리가 올바르게 할 수 있도록 도와 줄 수 있습니까? 실수를 말할 수 있다면, 무슨 뜻입니까?멀티 스레드 타이머가 올바르게 작동하지 않습니다.
public class TimerThreads implements ActionListener{
JFrame jFrame = new JFrame();
JLabel[] labels;
int second = 0;
int minute = 0;
String s = "";
String m = "";
int l = 0;
public TimerThreads(){
JLabel one = new JLabel();
JLabel two = new JLabel();
JLabel three = new JLabel();
JLabel four = new JLabel();
labels = new JLabel[]{one, two, three, four};
jFrame.setLayout(new GridLayout(0, 2, 5, 5));
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JButton start = new JButton("Start");
start.addActionListener(this);
JButton stop = new JButton("Stop");
stop.addActionListener(this);
jFrame.add(start);
jFrame.add(stop);
jFrame.setVisible(true);
jFrame.pack();
}
public static void main(String[] args) {
new TimerThreads();
}
@Override
public void actionPerformed(ActionEvent e) {
String select = e.getActionCommand();
switch(select){
case "Start":
jFrame.add(labels[l]);
jFrame.revalidate();
jFrame.repaint();
TimerThread t = new TimerThread(labels[l]);
t.start();
l++;
break;
case "Stop":
//
break;
}
}
class TimerThread extends Thread{
JLabel jLabel;
public TimerThread(JLabel jLabel) {
this.jLabel = jLabel;
}
@Override
public void run() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
second++;
if(String.valueOf(second).length() == 1){
s = "0";
}
else{
s = "";
}
if(second == 60){
second = 0;
s = "0";
minute++;
}
if(String.valueOf(minute).length() == 1){
m = "0";
}
jLabel.setText(m + String.valueOf(minute) + ":" + s + String.valueOf(second));
}
},0, 1000);
}
}
}
스윙 타이머 또는'javax.swing.Timer'를 사용해야 할 때'java.util.Timer'라는 잘못된 Timer를 사용하고 있습니다. 이것은 후자의 Timer가 Swing 이벤트 모델과 잘 작동하고 스레드 충돌을 방지하기 때문에 매우 중요합니다. 이것이 도움이되지 않으면 질문을 편집하고 스윙 타이머 시도를 보여주십시오. [스윙 타이머 튜토리얼] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)을 확인하십시오. –
다른 주요 문제점 (및 버그의 원인)은 s, m, second 및 minute를 포함하여 TimerThreads 클래스의 필드는 바깥 쪽 TimerThreads 클래스의 필드가 아니며 중첩 된 TimerTask 클래스의 필드 여야합니다. 이것이 모든 타이머가 같은 값을 공유하는 이유입니다. 다시 말해, Swing Timer를 사용해야하므로이 필드는 Swing Timer의 자체 ActionListener 필드 내에서 선언되어야합니다. –
도움을 주신 것에 감사드립니다. 나는 반응하고 일했다. – PengeDroid