私は1日のコースでハイウェイの密度を表示するために時間の経過を作成しました。データはdouble[][]
アレイdata
に保持され、data.length
は2880(各インデックスは30秒間隔を表します)およびdata[0].length
は約450(ハイウェイセクションの長さ全体の3次補間を表します)に保持されます。Chromeウェブページの要素上にマウスを移動すると、タイマーが速くなります
次のように時間の経過のための私のコードは次のとおりです。スムーズ
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);
}
}
アニメーション機能を、それは一般的に、私は定数までチョーク、私はそれを設定し、5秒、より長く多くを取りますパネル内で数百の線の着色および生成を引き起こす。
私が正しかったことを確かめるためには、Googleの「ストップウォッチ」で時刻を表示するときに表示されるGoogle Chromeウィジェットを使用しました。これを行うと、私はストップウォッチを実行したときに、アニメーションが大幅にスピードアップし、マウスを特定の要素(ハイパーリンク、上部のタブ、マウスのホバーリングに視覚的に反応する他のもの) 。これは、マウスを動かすか、ストップウォッチを実行しているときにのみ発生します。マウスを維持しても速度が上がらず、Chrome上でマウスを動かしている間(つまり、他のアプリケーションであれ)正常に動作するように見えます。誰もこの奇妙な行動を説明できますか?
編集:タブの再読み込み中にも発生しますが、再読み込みが終了した後ではありません。
EDIT 2:タイマーが高速化していることがわかりました。これは、Chromeの要素の上にマウスを移動するときに大幅にスピードアップし、時間の経過クラスとまったく同じ動作を持ってい
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) {
}
}
}
:私はミリ秒ごとに増加し、インデックスを印刷し、タイマーで小さなクラスを作成しました。理由は、この場合、println
が遅い方法であり、タイマーの更新よりも遅く実行するという理由が考えられます。繰り返しますが、Chromeがバックアップされたタイマーの速度を上げる理由を説明できますか?
私は、 'paint'が呼び出される時期を予測できないことを知っています。私がここでやっていることを避けようとしています(paintメソッドのプロパティを更新しています)。これは実際に私がこのクラスで元々持っていたものですが、描画速度が遅いため、 'timer'は準備が整う前にインデックスを更新してしまい、レンダリングやインデックス作成のバグやエラーが発生します。 – 17slim
ツールチップを使う限り、私は何も使っていません。 – 17slim
とにかく、インデックスとプログレスバーを更新し、それをタイマーに入れる方法を提案して作成しました(私が使っていた以前のバグは私が使っている新しいインデックス計算には表示されません) 。私はコードを更新しますが、その動作はそのままです。 – 17slim