我编写了这个简单的程序,它可以显示键盘按键,绘制短语“Hello World”,并在鼠标滚轮滚动时循环切换“Hello World”所选颜色。然而,存在一个问题:当鼠标滚轮滚动时,整个窗口都会变成空白(显示的是首次使组件可见时的默认灰色),然后再以新颜色重新绘制(仅对“Hello World”进行微小更改,似乎不需要重新绘制整个框架)。
空白发生的时间似乎与滚动鼠标轮的力度有关,如果我轻轻地滚动,几乎没有任何东西未被显示出来,但是强烈滚动可能会使窗口变空白2-3秒钟。
我尝试了双缓冲,认为这可能是某种屏幕闪烁,但没有任何改变,我不知道是什么原因导致了这种奇怪的效果。就像在发生滚轮运动事件时加载帧图像一样。(也许有一种方法可以立即退出滚轮事件,从而减少加载时间?(这只是我对可能解决方案的猜测))。
以下是代码。非常感谢您的任何想法。
空白发生的时间似乎与滚动鼠标轮的力度有关,如果我轻轻地滚动,几乎没有任何东西未被显示出来,但是强烈滚动可能会使窗口变空白2-3秒钟。
我尝试了双缓冲,认为这可能是某种屏幕闪烁,但没有任何改变,我不知道是什么原因导致了这种奇怪的效果。就像在发生滚轮运动事件时加载帧图像一样。(也许有一种方法可以立即退出滚轮事件,从而减少加载时间?(这只是我对可能解决方案的猜测))。
以下是代码。非常感谢您的任何想法。
package keymouse;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferStrategy;
import java.util.LinkedList;
import javax.swing.JFrame;
public class KeyMouse implements KeyListener,
MouseMotionListener, MouseListener, MouseWheelListener, Runnable {
boolean trailMode = false;
boolean exists = false;
display window;
LinkedList wordList;
LinkedList trailList;
LinkedList colorList;
Point mousePoint;
int TRAIL_SIZE = 10;
boolean init = true;
int FONT_SIZE = 32;
int mouseY;
int mouseX;
int y;
int colorCount = 0;
public static void main(String[] args) {
KeyMouse k = new KeyMouse();
k.run();
}
public KeyMouse() {
window = new display();
window.addKeyListener(this);
window.addMouseMotionListener(this);
window.addMouseListener(this);
window.addMouseWheelListener(this);
window.setBackground(Color.WHITE);
window.setForeground(Color.BLACK);
wordList = new LinkedList();
trailList = new LinkedList();
colorList = new LinkedList();
colorList.add(Color.BLACK);
colorList.add(Color.BLUE);
colorList.add(Color.YELLOW);
colorList.add(Color.GREEN);
colorList.add(Color.PINK);
}
@Override
public void keyTyped(KeyEvent e) {
// do nothing
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode;
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
stop();
}
keyCode = e.getKeyCode();
addMessage("Pressed:" + e.getKeyText(keyCode));
}
@Override
public void keyReleased(KeyEvent e) {
//do nothing
}
@Override
public void mouseDragged(MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
addLocation(p);
}
@Override
public void mouseMoved(MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
addLocation(p);
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
trailMode = true;
}
@Override
public void mouseReleased(MouseEvent e) {
trailMode = false;
}
@Override
public void mouseEntered(MouseEvent e) {
//do nothing
}
@Override
public void mouseExited(MouseEvent e) {
//do nothing
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
System.out.println(e.getWheelRotation());
colorCount++;
if (colorCount > 4) {
colorCount = 0;
}
window.setForeground((Color) colorList.get(colorCount));
}
@Override
public void run() {
window.createBufferStrategy(2);
BufferStrategy strategy = window.getBufferStrategy();
while (true) {
draw(strategy.getDrawGraphics());
strategy.show();
try {
Thread.sleep(20);
} catch (Exception ex) {
}
}
}
public void draw(Graphics g) {
//draw background
g.setColor(window.getBackground());
g.fillRect(0, 0, window.getWidth(), window.getHeight());
//draw Text
g.setColor(window.getForeground());
g.setFont(new Font("sansserif", Font.BOLD, 32));
int count = trailList.size();
if (trailList.size() > 1 && trailMode == false) {
count = 1;
}
if (exists == true) {
for (int i = 0; i < count; i++) {
Point p = (Point) trailList.get(i);
g.drawString("Hello World", p.x, p.y);
}
}
g.setColor(Color.BLACK);
y = 56;
for (int i = 0; i < wordList.size(); i++) {
String word = (String) wordList.get(i);
g.drawString((String) wordList.get(i), 100, y);
y += 32;
}
}
public void addMessage(String message) {
if (y >= window.getHeight()) {
wordList.remove(0);
}
wordList.add(message);
}
public void addLocation(Point h) {
exists = true;
trailList.addFirst(h);
if (trailList.size() > TRAIL_SIZE) {
trailList.removeLast();
}
}
public void printMessages() {
for (int i = 0; i < wordList.size(); i++) {
System.out.println(wordList.get(i));
}
}
private void stop() {
System.exit(0);
}
Timer
替代:while (true) { .. Thread.sleep(20);
- Andrew ThompsonRunnable
接口,你是否打算在后台线程中运行run()
方法?但事实并非如此,你直接调用了它。 - Christoph Walesch