I am changing the bounds of a JPanel using a Timer to get a sliding effect when someone hovers over a particular rectangular area, this is working as expected. There are buttons in the JPanel and they have different MouseEvent behaviors. But SOMETIMES it starts lagging or slides very slowly. Please, can anyone suggest what can I do, to ensure it performs well every time?
EDITED:
The buttonsPanel have button in it. buttonsPanel is added to a JLayeredPane which have bounds as rect. When JLayeredPane or JButton button is hovered mouse events are triggered. Mouse events then triggers the timer to slide the buttonsPanel and bring to it view.
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);
}
}
}
The primary issue is you are assuming that you have control over the paint engine. You don’t, in fact, the paint engine is at the mercy of the OS. This means that you can jump up and down all you like, but until the OS and Java’s paint engine are ready, nothing will happen.
In fact, if you call repaint repeatedly in quick succession you can find yourself flooding the paint engine with requests, slowing it down even further.
While not a solution to the whole problem, it will make your life vastly simpler take a look at the TimingFramework or Trident.
They are “animation” frameworks designed to take out the guess work and make your life easier. I personal use
TimingFrameworkfor all my animation and it works well.The timing frameworks work on a % over time. That is, you give it a time for a cycle and the frameworks will return a % value based on how far through that cycle they are. You can apply interpolations, allowing you to effect how fast a portion of the animation will play.
Tridenthas also been designed to provide the means to call other methods on your behalf, so it could set the bounds of the button pane for you, based on values you supply it.