Netbeans GUI 中的摆动计时器
Swing Timer in Netbeans GUI
这是我的第一个 Swing 应用程序,所以我使用了 NetBeans GUI Builder。
有一个 Start 按钮可以开始模拟(两个循环:外部按天数和内部按小时数)。在每次迭代中,循环都应该暂停。当您单击“停止”按钮时,模拟应该停止。我尝试了以下方法:
1)
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
Timer timer = new Timer(5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
while(presentDay <= numberOfDays){
jTextField2.setText(Integer.toString(presentDay));
for(; presentTime <= 18; presentTime++){
jTextField6.setText(Integer.toString(presentTime));
StringBuilder res = new StringBuilder();
for(Event ev: schedule[presentDay-1].day){
if((presentTime <= ev.getTimeFinish()) && (presentTime >= ev.getTimeStart())){
res.append(ev);
ev.setStatus(1);
}
}
currentEvent.setText(res.toString());
// Pause should here
}
presentTime = 9;
presentDay++;
}
}
});
timer.start();
}
2) 在主class构造函数中添加定时器
public PlanningSystem() {
initComponents();
...
timer = new Timer(5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
while(presentDay <= numberOfDays){
jTextField2.setText(Integer.toString(presentDay));
for(; presentTime <= 18; presentTime++){
jTextField6.setText(Integer.toString(presentTime));
StringBuilder res = new StringBuilder();
for(Event ev: schedule[presentDay-1].day){
if((presentTime <= ev.getTimeFinish()) && (presentTime >= ev.getTimeStart())){
res.append(ev);
ev.setStatus(1);
}
}
currentEvent.setText(res.toString());
// Pause here
}
presentTime = 9;
presentDay++;
}
}
});
}
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
timer.start();
}
但是这两种方式都不行。我希望你能帮助解决这个问题。
对不起我的英语:)
============================================= =========================
编辑后:
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
if(presentDay <= numberOfDays){
jTextField2.setText(Integer.toString(presentDay));
Timer tim = new Timer (5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(presentTime <= 18){
jTextField6.setText(Integer.toString(presentTime));
StringBuilder res = new StringBuilder();
for(Event ev: schedule[presentDay-1].day){
if((presentTime <= ev.getTimeFinish()) && (presentTime >= ev.getTimeStart())){
res.append(ev);
ev.setStatus(1);
}
}
currentEvent.setText(res.toString());
presentTime++;
}
}
});
tim.start();
presentTime = 9;
presentDay++;
}
}
问题出在你的 while 循环上。您在第一次调用计时器时将 presentDay
增加到 numberOfDays
。在那之后,什么都不会再改变了。
我相信(虽然由于您发布的部分代码,我不能确定)如果您去掉 while 循环,它会如您所愿地工作
编辑:(更好地理解你在做什么)
使用两个定时器是错误的。只需使用一个计时器,并在那里更新您的 presentDay 和 presentTime。
Timer tim = new Timer (5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
presentTime++;
if (presentTime == 24) {
presentTime = 0;
presentDay++;
}
//times how now been set
//update your GUI here
}
}
看看这是否有帮助,不过,为了模拟两个循环的使用,我使用了 BubbleSort
算法。尽管如前所述,删除单个 while 循环就可以做到这一点。由于在这种情况下它按预期工作,但如果列表很长,它将如何工作是值得怀疑的。否则你可以看看 SwingWorker.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimerExample {
private JLabel [] labels;
private static final int TOTAL_VALUES = 5;
private static final int GAP = 5;
private JButton startButton;
private JButton stopButton;
private Timer timer;
private int [] values = {
5, 10, 20, 2, 8
};
private int pass;
private int i;
private ActionListener timerActions = new ActionListener () {
@Override
public void actionPerformed ( ActionEvent ae ) {
if ( pass <= TOTAL_VALUES - 1 ) {
System.out.println ( "Pass: " + pass );
for ( int i = 0; i <= TOTAL_VALUES - 1 - pass; ++i ) {
System.out.println ( "i: " + i );
try {
int left = Integer.parseInt ( labels [ i ].getText () );
int right = Integer.parseInt ( labels [ i + 1 ].getText () );
System.out.println ( "[ " + i + " ] " + left + " [ " + ( i + 1 ) + " ] " + right );
if ( left > right ) {
String value = labels [ i ].getText ();
labels [ i ].setText ( labels [ i + 1 ].getText () );
labels [ i + 1 ].setText ( value );
}
} catch ( Exception ex ) {
ex.printStackTrace ();
}
}
++pass;
}
}
};
public TimerExample () {
pass = 1;
i = 0;
}
private void displayGUI () {
JFrame frame = new JFrame ( "" );
frame.setDefaultCloseOperation ( JFrame.DISPOSE_ON_CLOSE );
JPanel contentPane = new JPanel ();
contentPane.setLayout ( new BorderLayout ( GAP, GAP ) );
JPanel topPanel = new JPanel ();
createLabels ( topPanel );
contentPane.add ( topPanel, BorderLayout.CENTER );
JPanel bottomPanel = new JPanel ();
startButton = new JButton ( "Start" );
startButton.addActionListener ( new ActionListener () {
@Override
public void actionPerformed ( ActionEvent ae ) {
if ( !timer.isRunning () ) {
timer.start ();
}
}
} );
stopButton = new JButton ( "Stop" );
stopButton.addActionListener ( new ActionListener () {
@Override
public void actionPerformed ( ActionEvent ae ) {
if ( timer.isRunning () ) {
timer.stop ();
}
}
} );
bottomPanel.add ( startButton );
bottomPanel.add ( stopButton );
contentPane.add ( bottomPanel, BorderLayout.PAGE_END );
frame.setContentPane ( contentPane );
frame.pack ();
frame.setLocationByPlatform ( true );
frame.setVisible ( true );
timer = new Timer ( 1000, timerActions );
}
private void createLabels ( JPanel contentPane ) {
labels = new JLabel [ TOTAL_VALUES ];
for ( int i = 0; i < TOTAL_VALUES; ++i ) {
labels [ i ] = new JLabel ( "" + values [ i ], JLabel.CENTER );
contentPane.add ( labels [ i ] );
}
}
public static void main ( String [] args ) {
Runnable runnable = new Runnable () {
@Override
public void run () {
new TimerExample ().displayGUI ();
}
};
EventQueue.invokeLater ( runnable );
}
}
这是我的第一个 Swing 应用程序,所以我使用了 NetBeans GUI Builder。 有一个 Start 按钮可以开始模拟(两个循环:外部按天数和内部按小时数)。在每次迭代中,循环都应该暂停。当您单击“停止”按钮时,模拟应该停止。我尝试了以下方法: 1)
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
Timer timer = new Timer(5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
while(presentDay <= numberOfDays){
jTextField2.setText(Integer.toString(presentDay));
for(; presentTime <= 18; presentTime++){
jTextField6.setText(Integer.toString(presentTime));
StringBuilder res = new StringBuilder();
for(Event ev: schedule[presentDay-1].day){
if((presentTime <= ev.getTimeFinish()) && (presentTime >= ev.getTimeStart())){
res.append(ev);
ev.setStatus(1);
}
}
currentEvent.setText(res.toString());
// Pause should here
}
presentTime = 9;
presentDay++;
}
}
});
timer.start();
}
2) 在主class构造函数中添加定时器
public PlanningSystem() {
initComponents();
...
timer = new Timer(5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
while(presentDay <= numberOfDays){
jTextField2.setText(Integer.toString(presentDay));
for(; presentTime <= 18; presentTime++){
jTextField6.setText(Integer.toString(presentTime));
StringBuilder res = new StringBuilder();
for(Event ev: schedule[presentDay-1].day){
if((presentTime <= ev.getTimeFinish()) && (presentTime >= ev.getTimeStart())){
res.append(ev);
ev.setStatus(1);
}
}
currentEvent.setText(res.toString());
// Pause here
}
presentTime = 9;
presentDay++;
}
}
});
}
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
timer.start();
}
但是这两种方式都不行。我希望你能帮助解决这个问题。 对不起我的英语:)
============================================= ========================= 编辑后:
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
if(presentDay <= numberOfDays){
jTextField2.setText(Integer.toString(presentDay));
Timer tim = new Timer (5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(presentTime <= 18){
jTextField6.setText(Integer.toString(presentTime));
StringBuilder res = new StringBuilder();
for(Event ev: schedule[presentDay-1].day){
if((presentTime <= ev.getTimeFinish()) && (presentTime >= ev.getTimeStart())){
res.append(ev);
ev.setStatus(1);
}
}
currentEvent.setText(res.toString());
presentTime++;
}
}
});
tim.start();
presentTime = 9;
presentDay++;
}
}
问题出在你的 while 循环上。您在第一次调用计时器时将 presentDay
增加到 numberOfDays
。在那之后,什么都不会再改变了。
我相信(虽然由于您发布的部分代码,我不能确定)如果您去掉 while 循环,它会如您所愿地工作
编辑:(更好地理解你在做什么)
使用两个定时器是错误的。只需使用一个计时器,并在那里更新您的 presentDay 和 presentTime。
Timer tim = new Timer (5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
presentTime++;
if (presentTime == 24) {
presentTime = 0;
presentDay++;
}
//times how now been set
//update your GUI here
}
}
看看这是否有帮助,不过,为了模拟两个循环的使用,我使用了 BubbleSort
算法。尽管如前所述,删除单个 while 循环就可以做到这一点。由于在这种情况下它按预期工作,但如果列表很长,它将如何工作是值得怀疑的。否则你可以看看 SwingWorker.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimerExample {
private JLabel [] labels;
private static final int TOTAL_VALUES = 5;
private static final int GAP = 5;
private JButton startButton;
private JButton stopButton;
private Timer timer;
private int [] values = {
5, 10, 20, 2, 8
};
private int pass;
private int i;
private ActionListener timerActions = new ActionListener () {
@Override
public void actionPerformed ( ActionEvent ae ) {
if ( pass <= TOTAL_VALUES - 1 ) {
System.out.println ( "Pass: " + pass );
for ( int i = 0; i <= TOTAL_VALUES - 1 - pass; ++i ) {
System.out.println ( "i: " + i );
try {
int left = Integer.parseInt ( labels [ i ].getText () );
int right = Integer.parseInt ( labels [ i + 1 ].getText () );
System.out.println ( "[ " + i + " ] " + left + " [ " + ( i + 1 ) + " ] " + right );
if ( left > right ) {
String value = labels [ i ].getText ();
labels [ i ].setText ( labels [ i + 1 ].getText () );
labels [ i + 1 ].setText ( value );
}
} catch ( Exception ex ) {
ex.printStackTrace ();
}
}
++pass;
}
}
};
public TimerExample () {
pass = 1;
i = 0;
}
private void displayGUI () {
JFrame frame = new JFrame ( "" );
frame.setDefaultCloseOperation ( JFrame.DISPOSE_ON_CLOSE );
JPanel contentPane = new JPanel ();
contentPane.setLayout ( new BorderLayout ( GAP, GAP ) );
JPanel topPanel = new JPanel ();
createLabels ( topPanel );
contentPane.add ( topPanel, BorderLayout.CENTER );
JPanel bottomPanel = new JPanel ();
startButton = new JButton ( "Start" );
startButton.addActionListener ( new ActionListener () {
@Override
public void actionPerformed ( ActionEvent ae ) {
if ( !timer.isRunning () ) {
timer.start ();
}
}
} );
stopButton = new JButton ( "Stop" );
stopButton.addActionListener ( new ActionListener () {
@Override
public void actionPerformed ( ActionEvent ae ) {
if ( timer.isRunning () ) {
timer.stop ();
}
}
} );
bottomPanel.add ( startButton );
bottomPanel.add ( stopButton );
contentPane.add ( bottomPanel, BorderLayout.PAGE_END );
frame.setContentPane ( contentPane );
frame.pack ();
frame.setLocationByPlatform ( true );
frame.setVisible ( true );
timer = new Timer ( 1000, timerActions );
}
private void createLabels ( JPanel contentPane ) {
labels = new JLabel [ TOTAL_VALUES ];
for ( int i = 0; i < TOTAL_VALUES; ++i ) {
labels [ i ] = new JLabel ( "" + values [ i ], JLabel.CENTER );
contentPane.add ( labels [ i ] );
}
}
public static void main ( String [] args ) {
Runnable runnable = new Runnable () {
@Override
public void run () {
new TimerExample ().displayGUI ();
}
};
EventQueue.invokeLater ( runnable );
}
}