gpt4 book ai didi

java - 将鼠标移到 Chrome 网页元素上时计时器会加快

转载 作者:行者123 更新时间:2023-12-01 09:34:24 28 4
gpt4 key购买 nike

我创建了一个延时来显示一天中高速公路上的密度。数据保存在 double[][] 数组 data 中,其中 data.length 为 2880(每个索引代表 30 秒的间隔) ) 且 data[0].length 约为 450(表示跨公路路段长度的三次插值)。

我的延时代码如下:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.Timer;

public class TimeLapse extends JPanel {
static double[][] data;
int index = 0;
double max;
double lineWidth;
Timer timer;
final JProgressBar progressBar = new JProgressBar(0, 2879);
BufferedImage[] images;
Color colors[][];

public static void main(String[] args) {
data=getData(); //arbitrary method to get interpolated data
new TimeLapse(data, 90);
}

public TimeLapse(double[][] data1, double max) {
data = data1;
this.max = max;
JFrame frame = new JFrame("Timelapse");
frame.setPreferredSize(new Dimension(800, 600));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.NORTH;
c.gridwidth = 1;
c.gridx = 0;
c.gridheight = 1;
c.weightx = 1;
c.weighty = .01;
c.gridy = 0;
frame.add(progressBar, c);
c.anchor = GridBagConstraints.SOUTH;
c.gridy = 1;
c.gridheight = 9;
c.weighty = 1;
frame.add(this, c);
frame.pack();
getColorArray();
frame.setVisible(true);
int dataLength;
dataLength = data.length;
// Make the animation 5 seconds long
int delay = (int) (5000d / dataLength);
timer = new Timer(delay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateIndex();
repaint();
Toolkit.getDefaultToolkit().sync();
}
});
timer.start();
}

private void getColorArray() {
double cutOff = max / 2;
colors = new Color[data.length][data[0].length];
for (int index = 0; index < data.length; index++) {
for (double x = 0; x < data[0].length; x++) {
colors[index][(int) x] =
getColor(data[index][(int) x], cutOff);
}
}
}

private void updateIndex() {
index = index < data.length - 1 ? index + 1 : 0;
progressBar.setValue(2879 * index / data.length);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int panelHeight = getHeight();
lineWidth = ((double) getWidth()) / ((double) (data[0].length));
// guaranteed counter, as doing it in timer's ActionListener could overlap with rendering

for (double x = 0; x < data[0].length; x++) {
g2.setColor(colors[index][(int) x]);
double rectHeight = panelHeight * data[index][(int) x] / max;
g2.fillRect((int) (x * lineWidth),
(int) (panelHeight - rectHeight),
(int) (lineWidth + 1), (int) rectHeight + 1);
}
g2.dispose();
}

private Color getColor(double value, double cutOff) {
int hueR, hueG, hueB = 0;
if (value < cutOff) {
hueG = 255;
hueR = (int) (255 * value / (cutOff));
} else if (max != cutOff) {
hueR = 255;
hueG = (int) (255 - (255 * (value - cutOff) / (max - cutOff)));
} else {
hueR = 255;
hueG = 0;
}

hueR = (hueR < 0) ? 0 : ((hueR > 255) ? 255 : hueR);
hueG = (hueG < 0) ? 0 : ((hueG > 255) ? 255 : hueG);
hueB = (hueB < 0) ? 0 : ((hueB > 255) ? 255 : hueB);
return new Color(hueR, hueG, hueB);
}
}

动画运行流畅,但通常需要比我设置的五秒长得多的时间,我将其归因于面板中不断着色和生成数百条线。

为了验证我的正确性,并且它确实比应有的速度慢得多,我使用了当您用 Google“秒表”来计时时出现的 Google Chrome 小部件。这样做时,我发现当我运行秒表时,动画速度大大加快,每当我将鼠标移到某些元素上时(超链接、顶部的选项卡以及似乎对鼠标悬停给出视觉响应的任何其他内容) 。仅当我移动鼠标或运行秒表时才会发生这种情况;保持鼠标静止并不会加快速度,而且似乎只有将鼠标悬停在 Chrome 上时才会出现这种行为(即任何其他应用程序都可以)。谁能解释一下这种奇怪的行为吗?

编辑:重新加载选项卡时也会发生这种情况,但重新加载完成后不会发生。

编辑2:我现在可以确定计时器正在加速。我创建了一个带有计时器的小类,该计时器每毫秒打印一个递增的索引:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

public class TimerTest {
static int index = 0;

public static void main(String[] args) {
Timer t = new Timer(1, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(index++);
}
});
t.start();

while (true) {
}
}
}

这与延时类具有完全相同的行为,当将鼠标移动到 Chrome 的元素上时,速度会大大加快。我相信原因是,在这种情况下, println 是一个缓慢的方法,并且执行速度比计时器更新慢。再说一次,有人能解释一下为什么 Chrome 专门加速备份计时器吗?

最佳答案

绘画方法仅用于绘画。

您不应该在绘画方法中更改类的属性。

也就是说,您无法控制 Swing 何时确定组件需要重新绘制。因此,可能有一些系统调用导致组件被重新绘制,因此更改属性的频率比您想象的要频繁。

例如,您不应该更新“索引”变量或进度条值。相反,您的计时器应该调用一个方法来更改这些属性,然后该方法应该调用面板上的重绘。

This only happens when I move the mouse

也许面板上有工具提示,这会导致面板被重新绘制。

这很容易测试,只需在 PaintComponent() 方法中添加一条 System.out.println(...) 语句即可查看它的显示频率是否比计时器的 5 秒更频繁。

关于java - 将鼠标移到 Chrome 网页元素上时计时器会加快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39127643/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com