问题
I think I may have found a platform issue with openjdk-1.8.0_45 under ubuntu 15.04. The following program compiles and runs:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class TimerTime extends JPanel implements ActionListener
{
private JLabel timeLabel;
public TimerTime()
{
timeLabel = new JLabel( String.valueOf(System.currentTimeMillis());
add( timeLabel );
Timer timer = new Timer(50, this);
timer.setInitialDelay(1);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e)
{
//System.out.println(e.getSource());
timeLabel.setText(String.valueOf(System.currentTimeMillis()));
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("TimerTime");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TimerTime() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
The time visually updates about twice per second until any kind of input happens to it - the mouse moves over it, it gets dragged, etc. Then it will get updated at the proper rate, or at least much faster. Does this happen on your system? Can anyone provide an explanation or theory for this behavior? If I put prints each time timeLabel
's setText()
is called, I can see that it's being called approximately 20 times per second, but despite this the actual on-screen window is only being updated twice per second until other input events happen.
回答1:
Why are you using AWT instead of Swing? I would use a JFrame
Why are you doing custom painting? Just use a JLabel and add the JLabel to the JFrame and then you use the
setText(...)
method. Don't reinvent the wheel.Why are you using Thread.sleep(). Use a Timer. A Timer is used to schedule an event. Read the section from the Swing tutorial on How to Use Swing Timers for more information.
Here is a complete example to get you started:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class TimerTime extends JPanel implements ActionListener
{
private JLabel timeLabel;
public TimerTime()
{
timeLabel = new JLabel( new Date().toString() );
add( timeLabel );
Timer timer = new Timer(1000, this);
timer.setInitialDelay(1);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e)
{
//System.out.println(e.getSource());
timeLabel.setText( new Date().toString() );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("TimerTime");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TimerTime() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
来源:https://stackoverflow.com/questions/31760682/java-component-not-updating-most-of-the-time