¿Por qué a veces el efecto Deslizante en mi JPanel se retrasa?
Pregunta
Estoy cambiando los límites de un JPanel
usando un Timer
Para obtener un efecto de deslizamiento cuando alguien pasa el cursor sobre un área rectangular en particular, esto funciona como se esperaba.Hay botones en el JPanel
y tienen diferentes MouseEvent
comportamientos.Pero A VECES comienza a retrasarse o se desliza muy lentamente.Por favor, ¿alguien puede sugerir qué puedo hacer para asegurarme de que funcione bien en todo momento?
EDITADO:
El buttonsPanel
tener button
en eso. buttonsPanel
se agrega a un JLayeredPane
que tienen límites como rect
.Cuando JLayeredPane o JButton button
es hovered
Se activan los eventos del mouse.Los eventos del mouse activan el temporizador para slide the buttonsPanel
y traerle la vista.
class MyActionListener implements ActionListener {
private static final int frames = 50;
int count = 0;
private final Timer timer = new Timer(1, this);
public void start() {
timer.start();
}
@Override
public void actionPerformed(ActionEvent ae) {
if (count >= frames) {
timer.stop();
} else {
count = count + 1;
buttonsPanel.setBounds(hidden_width - hidden_width * count / frames, 0, hidden_width, frameHeight);
}
}
}
class MyMouseListener extends MouseAdapter {
private MyActionListener timerListener;
@Override
public void mouseEntered(final MouseEvent event) {
final Color color = new Color(50, 50, 50);
if (event.getSource() instanceof JButton) {
final JButton button = (JButton) event.getSource();
button.setBackground(color);
buttonsPanel.setVisible(true);
} else if (!buttonsPanel.isVisible()) {
buttonsPanel.setVisible(true);
timerListener = new MyActionListener();
timerListener.start();
}
}
@Override
public void mouseExited(final MouseEvent event) {
Point point = new Point(0, 0);
if (event.getSource() instanceof JButton) {
final JButton button = (JButton) event.getSource();
point = button.getLocation();
button.setBackground(Windows8GUI.color);
}
Rectangle rect = new Rectangle(0, 0, hidden_width, frameHeight);
if (!rect.contains(point.x + event.getX(), point.y + event.getY())) {
buttonsPanel.setVisible(false);
buttonsPanel.setBounds(0, 0, hidden_width, frameHeight);
}
}
}
Solución
El problema principal es que usted asume que tiene control sobre el motor de pintura.De hecho, no es así, el motor de pintura está a merced del sistema operativo.Esto significa que puedes saltar hacia arriba y hacia abajo todo lo que quieras, pero hasta que el sistema operativo y el motor de pintura de Java estén listos, no sucederá nada.
De hecho, si llamas a repintar repetidamente en rápida sucesión, puedes encontrarte inundando el motor de pintura con solicitudes, ralentizándolo aún más.
Si bien no es una solución a todo el problema, le hará la vida mucho más sencilla. Eche un vistazo a Marco temporal o Tridente.
Son marcos de "animación" diseñados para eliminar las conjeturas y hacerle la vida más fácil.yo uso personal TimingFramework
para toda mi animación y funciona bien.
Los marcos de tiempo funcionan en un % a lo largo del tiempo.Es decir, le da un tiempo para un ciclo y los marcos devolverán un valor de porcentaje en función de qué tan avanzado esté ese ciclo.Puede aplicar interpolaciones, lo que le permitirá determinar la velocidad con la que se reproducirá una parte de la animación.
Trident
También ha sido diseñado para proporcionar los medios para llamar a otros métodos en su nombre, de modo que pueda establecer los límites del panel de botones, según los valores que le proporcione.
Otros consejos
De hecho, si llamas a repintar repetidamente en rápida sucesión, puedes encontrarte inundando el motor de pintura con solicitudes, ralentizándolo aún más.
Creo que este es el verdadero problema.Intente aumentar el retraso entre los eventos del temporizador de 1 a 10-50 y debería funcionar mucho mejor.
Para conocer muchos procedimientos para crear esos (y muchos otros) efectos, solo puedo recomendar el Libro Clientes asquerosamente ricos.En esta página también encontrará muchos ejemplos de los efectos tratados en el libro.