I'm trying to change current visible in card layout with slide effect. But I see a flick at the start of slide which I'm not able to debug/solve. How can I avoid that flick?
Here is sample code to reproduce error:
import java.awt.CardLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new CardLayout());
JLabel label1 = new JLabel("Harry Joy");
panel.add(label1, "1");
JLabel label2 = new JLabel("Harsh Raval");
panel.add(label2, "2");
frame.add(panel);
frame.pack();
frame.setVisible(true);
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
label2.setLocation(label1.getX() + 10 - label1.getWidth(), label1.getY());
label1.setLocation(label1.getX() + 10, label1.getY());
label2.setVisible(true);
}
label2.setVisible(false);
CardLayout cl = (CardLayout)panel.getLayout();
cl.next(panel);
}
}
Here at first label1
("Harry Joy") is displayed. Then I make label2
("Harsh Raval") visible and try to change location of both to provide a slide effect. But what happening here is first time both labels are displayed on top of each other and then it starts to slide. How can I stop that, I mean displaying both labels on top of each other? You can get better idea of what I mean if you run it once.
May be this http://java-sl.com/tip_slider.html ?
a few comments and could be comments only
idea with
Thread.sleep
is correct but started only fromRunnable.Thread
for Swing GUI is there
Swing Timer
,Swing Timer
guarantee to move any of (without flickering with already) visibleJComponents
layed by standardLayoutManager
but in this (my code example) case I'm again using Swing Timer nor that all events would be done on EDT, by invoking from Runnable living own life without impact to the rest of Swing events, GUI e.i.,
notice this issue is based on AWT nested / inherits, for example for JComboBoxes popup (resize and with doLayout()) doesn't works
The main problem is that you are stepping on CardLayout's toes. CardLayout both manages bounds (location and size) and visibility of your components, so your loop here:
is conflicting with what CardLayout does. By default, CardLayout will automatically show the first component you added and hide all the others. It also sets up the bounds of all components to the same bounds.
At the end of the first iteration, the visibility of label2 changes (from
false
totrue
) which eventually triggers your CardLayout to reperform the layout of your components which sets the bounds of all the components to the same bounds which is why you are seeing the overlapping. CardLayout is not meant to have multiple components visible simultaneously.Note that you are running all this off the EDT (Event Dispatching Thread) which is really a bad idea. It can cause deadlocks and unpredictable behaviour (such as the one you are seeing here).