Java7u40中的javax.swing.Timer减速 [英] javax.swing.Timer slowdown in Java7u40

查看:105
本文介绍了Java7u40中的javax.swing.Timer减速的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

同时调用javax.swing.Timer #start(),

Invoke javax.swing.Timer#start() same time,

7u25没问题。

但7u40是个大问题。

but 7u40 is big problem.

太迟了调用ActionListener#actionPerformed。 (基本上同一时间调用u25)

Too laggy invoke ActionListener#actionPerformed. (basically same time invoke u25)

u25和u40之间完全不同的移动。 (我使用的是Windows 8)
我的错误报告,但仍然没有添加错误跟踪系统。甲骨文破坏摇摆应用程序?

Totally different move between u25 and u40. (I use Windows 8) I bug report but still not add bug tracking system. Oracle crushing swing apps?

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class TimerProblem extends JComponent {

        int red = 0;

        TimerProblem(final long startMs) {
                setPreferredSize(new Dimension(10, 10));

                Timer t = new Timer(16, new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                                red = (int)(System.currentTimeMillis() - startMs) % 255;
                                repaint();
                        }

                });
                t.setInitialDelay(1000);
                t.start();
        }

        @Override
        protected void paintComponent(Graphics g) {
                g.setColor(new Color(red, 255 - red, 0));
                g.fillRect(0, 0, getWidth(), getHeight());
        }

        public static void main(String[] args) {
                JFrame f = new JFrame();
                Container c = f.getContentPane();

                c.setLayout(new GridLayout(10, 10));
                long startMs = System.currentTimeMillis();
                for (int i = 0; i < 100; i++) {
                        c.add(new TimerProblem(startMs));
                }
                f.pack();
                f.setVisible(true);
        }

}


推荐答案

最后我写DIY重绘管理类.. :(

Finally I write DIY repaint management class .. :(

import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.Timer;

/**
 * EffectTimer
 */
public class EffectTimer {

    /**
     * All of effect timers in instance of this class.
     */
    static class GlobalTimer implements ActionListener {

        List<EffectTimer> registeredEffects = new ArrayList<>();

        Timer timer = new Timer(16, this);

        public void start(final EffectTimer t) {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    internalStart(t);
                }

            });
        }

        void internalStart(EffectTimer t) {
            int initialDelay = Math.max(0, (int) (t.getEffectStartTime() - System.currentTimeMillis()));
            if(timer.getInitialDelay() >= initialDelay) {
                timer.setInitialDelay(initialDelay);
            }
            if(!registeredEffects.contains(t)) {
                registeredEffects.add(t);
                if(registeredEffects.size() == 1) {
                    timer.start();
                }
            }
        }

        void stop(final EffectTimer t) {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    registeredEffects.remove(t);
                    checkStop();
                }

            });
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            long now = e.getWhen();

            Iterator<EffectTimer> iter = registeredEffects.iterator();
            while(iter.hasNext()) {
                EffectTimer t = iter.next();
                long elapsedMs = now - t.getEffectStartTime();

                if(elapsedMs > 0) {
                    float p = elapsedMs / (float)t.getEffectLengthMs();
                    if(p >= 1.0f) {
                        iter.remove();
                        t.stop();
                    } else {
                        if(t.isReversed()) {
                            p = 1.0f - p;
                        }
                        t.progressChanged(p);
                    }
                }
            }

            checkStop();
        }

        void checkStop() {
            if(registeredEffects.isEmpty()) {
                timer.stop();
            }
        }

        public int getRunningTimerCount() {
            return registeredEffects.size();
        }

        public void stopAll() {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    registeredEffects.clear();
                    checkStop();
                }

            });
        }

    }

    static final GlobalTimer GTIMER = new GlobalTimer();

    int effectLengthMs = -1;

    long effectStartMs = -1;

    float progress = 0.0f;

    boolean reversed = true;

    public long getEffectStartTime() {
        return effectStartMs;
    }

    public int getEffectLengthMs() {
        return effectLengthMs;
    }

    public void start(int lengthMs) {
        start(lengthMs, System.currentTimeMillis());
    }

    public void start(int lengthMs, long startMs) {
        effectLengthMs = lengthMs;
        effectStartMs = startMs;

        reversed = false;
        progress = 0.0f;
        GTIMER.start(this);
    }

    public boolean isReversed() {
        return reversed;
    }

    public void reverse(final int lengthMs) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                internalReverse(lengthMs);
            }

        });
    }

    void internalReverse(int lengthMs) {
        reversed = !reversed;

        effectLengthMs = lengthMs;
        int adjust = reversed ? (int)(lengthMs * (1.0f - progress)) : (int)(lengthMs * progress);
        effectStartMs = System.currentTimeMillis() - adjust;

        GTIMER.start(this);
    }

    final public void progressChanged(float p) {
        progress = p;
        run(p);
    }

    /**
     * 0.0f to 1.0f effect progress.
     * <code>Float.compare(progress, 1.0f) >= 0</code> to end progress.
     */
    protected void run(float p) {}

    public void stop() {
        progress = reversed ? 0.0f : 1.0f;
        GTIMER.stop(this);
    }

    public boolean isRunning() {
        return 0.0f < progress && progress < 1.0f;
    }

    public float getProgress() {
        return progress;
    }

    public static int getRunningTimerCount() {
        return GTIMER.getRunningTimerCount();
    }

    public static void stopAll() {
        GTIMER.stopAll();
    }

}

这篇关于Java7u40中的javax.swing.Timer减速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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