MouseWheel Flicker, más sobre el por qué
Frecuentes
Visto 191 equipos
1
Hace unos días publiqué una pregunta sobre un programa que provocaba que el texto de la pantalla cambiara de color cuando se desplazaba la rueda del ratón. Desafortunadamente, fue una pregunta mal formulada con demasiado código publicado para ser particularmente útil.
Recibí varias respuestas, una de las cuales fue del usuario trashdog que publicó algo que solucionó el problema (que se puede encontrar en la parte inferior de esta página aquí: La ventana se queda en blanco durante el evento MouseWheelMotion), sin embargo, después de leer las descripciones de clase de todas las cosas que no sabía en el programa que publicó y pasar por su ejecución, no entiendo por qué logra un efecto diferente al mío.
El suyo parece registrar cada movimiento de la rueda del mouse mientras que el mío solo hace el movimiento inicial. También varias personas comentaron que probablemente no pudieron replicar el efecto de mi programa porque era muy grande.
A continuación se muestra una versión extremadamente simplificada que aún provoca el mismo efecto (espero).
Pregunta: ¿Qué es fundamental ¿Cuál es la diferencia entre los dos programas que corrige que la pantalla se quede en blanco cuando se procesan los eventos de la rueda del mouse?
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;
import javax.swing.JFrame;
public class WheelPrinter implements MouseWheelListener, Runnable {
JFrame frame;
LinkedList colorList;
int colorCount;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
WheelPrinter w = new WheelPrinter();
w.run();
}
public WheelPrinter() {
frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addMouseWheelListener(this);
frame.setVisible(true);
frame.setBackground(Color.WHITE);
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 mouseWheelMoved(MouseWheelEvent e) {
colorChange();
}
@Override
public void run() {
while(true) {
draw(frame.getGraphics());
try {
Thread.sleep(20);
} catch (Exception ex) {
}
}
}
public void draw(Graphics g) {
g.setColor(frame.getBackground());
g.fillRect(0,0,frame.getWidth(),frame.getHeight());
g.setFont(new Font("sansserif", Font.BOLD, 32));
g.setColor(frame.getForeground());
g.drawString("yes", 50, 50);
}
public void colorChange() {
colorCount++;
if (colorCount > 4) {
colorCount = 0;
}
frame.setForeground((Color) colorList.get(colorCount));
}
}
(Intente girar la rueda del mouse muy fuerte si intenta ejecutar mi código y se volverá aún más obvio)
2 Respuestas
1
while(true) {
es bucle sin fin, sin interrupción; feutilizan el
Swing Timer
en lugar deRunnable#Thread
retrasado porThread.Sleep()
pintar a la
JPanel
orJComponent
, no directamente a laJFrame
toda la pintura al
Swing JComponent
debe hacerse enpaintComponent()
más en el Tutorial de gráficos 2D
editar
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* based on example by @trashgod
*
* @see http://stackoverflow.com/a/10970892/230513
*/
public class ColorWheel extends JPanel {
private static final int N = 32;
private static final long serialVersionUID = 1L;
private final Queue<Color> clut = new LinkedList<Color>();
private final JLabel label = new JLabel();
public ColorWheel() {
for (int i = 0; i < N; i++) {
clut.add(Color.getHSBColor((float) i / N, 1, 1));
}
//clut.add(Color.BLACK);
//clut.add(Color.BLUE);
//clut.add(Color.YELLOW);
//clut.add(Color.GREEN);
//clut.add(Color.PINK);
label.setFont(label.getFont().deriveFont(36f));
label.setForeground(clut.peek());
label.setText("@see http://stackoverflow.com/a/10970892/230513");
setBackground(Color.white);
add(label);
label.addMouseWheelListener(new MouseAdapter() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
label.setForeground(clut.peek());
clut.add(clut.remove());
}
});
}
@Override
public Dimension getPreferredSize() {
int w = SwingUtilities.computeStringWidth(label.getFontMetrics(
label.getFont()), label.getText());
return new Dimension(w + 20, 80);
}
private void display() {
JFrame f = new JFrame("ColorWheel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ColorWheel().display();
}
});
}
}
Respondido el 12 de junio de 12 a las 22:06
1
El fundamental la diferencia es que está tratando de interactuar con el objeto Graphics desde el hilo incorrecto y sin saber nada sobre el estado en el que se encuentra el objeto Graphics en ese momento.
La forma generalmente correcta de interactuar con un objeto Graphics en Swing es creando un componente personalizado que anule el paintComponent(Graphics)
método. Haces tu dibujo mientras estás dentro de ese método.
Su método colorChange() puede decirle a su componente que se vuelva a dibujar llamando repaint()
, que eventualmente conducirá a una llamada a paintComponent(Graphics)
en el hilo correcto en el momento correcto.
Respondido el 13 de junio de 12 a las 01:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas java swing graphics mousewheel mouselistener or haz tu propia pregunta.
¡Muchas gracias! ¿Qué significa fe? ¿Y el programa no permanecerá abierto y escuchando si no hay un ciclo while que lo mantenga funcionando y dibujando? - John Smith
aaaach, realmente no puedo ver la razón para molestarme con los gráficos, especialmente en el caso de que vinculaste un gran ejemplo de @trashgod, algunos cambios más que menores, no importantes para la salud en este mundo, mira mi edición aquí - mKorbel