Java组件大部分时间没有更新 [英] Java component not updating most of the time

查看:171
本文介绍了Java组件大部分时间没有更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我可能在ubuntu 15.04下找到了openjdk-1.8.0_45的平台问题。以下程序编译并运行:

  import java.awt。*; 
import java.awt.event。*;
import java.util。*;
import javax.swing。*;
import javax.swing.Timer;

公共类TimerTime扩展JPanel实现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();
}

@覆盖
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();
}
});
}
}

时间视觉上每秒更新两次,直到任何种类的输入发生在它上面 - 鼠标在它上面移动,它被拖动等,然后它会以适当的速率更新,或者至少快得多。这是否发生在您的系统上?任何人都可以为此行为提供解释或理论?如果每次打印照片 timeLabel 的 setText(),我都会看到它被称为大约20但是尽管如此,实际的屏幕窗口每秒只更新两次,直到发生其他输入事件为止。

解决方案


  1. 你为什么使用AWT而不是Swing?我会使用JFrame


  2. 你为什么要做自定义绘画?只需使用JLabel并将JLabel添加到JFrame中,然后使用 setText(...)方法。不要重新发明轮子。


  3. 你为什么使用Thread.sleep()。使用计时器。计时器用于安排事件。阅读 Swing定时器的使用方法中的Swing教程部分以获得更多信息。


以下是一个完整的示例:

  import java.awt。*; 
import java.awt.event。*;
import java.util。*;
import javax.swing。*;
import javax.swing.Timer;

公共类TimerTime扩展JPanel实现ActionListener
{
private JLabel timeLabel;

public TimerTime()
{
timeLabel = new JLabel(new Date()。toString());
add(timeLabel);

定时器定时器=新定时器(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();
}
});
}
}


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

  2. 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.

  3. 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();
            }
        });
    }
}

这篇关于Java组件大部分时间没有更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆