我试图用幻灯片效果来改变卡布局当前可见。 但我看到在滑动开始轻弹这我不能调试/解决。 我怎样才能避免甩尾?
下面是示例代码重现错误:
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);
}
}
在这里,在第一label1
(“哈利·喜悦”)显示。 然后,我让label2
(“苛刻拉瓦尔”)可见,并试图改变这两个位置提供了幻灯片效果。 但是,发生在这里是第一次两个标签显示在彼此的顶部,然后它开始滑动。 我怎样才能阻止这一点,我的意思是在彼此的顶部显示这两个标签? 你可以得到的,如果你运行一次我在说什么更好的主意。
主要的问题是,你在CardLayout的脚趾踩着。 CardLayout都在这里管理范围(位置和大小),以及您的组件的可见性,使您的循环:
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);
}
是什么CardLayout不冲突。 默认情况下,CardLayout会自动显示你添加的第一个组件,并隐藏所有其他人。 它还设置了所有的组件相同的边界的边界。
在第一次迭代结束的LABEL2变化的可见性(从false
到true
)最终触发您CardLayout来再进行你的组件的布局,将所有的组件相同的边界的边界这就是为什么你看到的重叠。 CardLayout并不意味着同时有肉眼可见的多个组件。
请注意,您正在运行的这一切离EDT(事件指派线程),这实在是一个糟糕的主意。 它可能导致死锁和不可预知的行为(如一个你在这里看到的)。
可能这http://java-sl.com/tip_slider.html ?
一些意见和可能是唯一的评论
有想法Thread.sleep
是正确的,但只从开始Runnable.Thread
对Swing GUI的是有Swing Timer
,
Swing Timer
保证移动任何的(不含已经在闪烁)可见JComponents
通过标准奠定LayoutManager
但在这(我的代码示例)的情况下,我再次使用Swing的计时器,也不是所有的事件将在美国东部时间来完成,从Runnable的生活自己的生活调用,而不影响的Swing事件,GUI EI的其余部分,
注意到这个问题是基于AWT嵌套/继承,例如用于JComboBoxes弹出(调整大小,并用的doLayout())不工作
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ShakingButtonDemo implements Runnable {
private JButton button;
private JRadioButton radioWholeButton;
private JRadioButton radioTextOnly;
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new ShakingButtonDemo());
}
@Override
public void run() {
radioWholeButton = new JRadioButton("The whole button");
radioTextOnly = new JRadioButton("Button text only");
radioWholeButton.setSelected(true);
ButtonGroup bg = new ButtonGroup();
bg.add(radioWholeButton);
bg.add(radioTextOnly);
button = new JButton(" Shake with this Button ");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
shakeButton(radioWholeButton.isSelected());
}
});
JPanel p1 = new JPanel();
p1.setBorder(BorderFactory.createTitledBorder("Shake Options"));
p1.setLayout(new GridLayout(0, 1));
p1.add(radioWholeButton);
p1.add(radioTextOnly);
JPanel p2 = new JPanel();
p2.setLayout(new GridLayout(0, 1));
p2.add(button);
JFrame frame = new JFrame();
frame.setTitle("Shaking Button Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(p1, BorderLayout.NORTH);
frame.add(p2, BorderLayout.SOUTH);
frame.setSize(240, 160);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void shakeButton(final boolean shakeWholeButton) {
final Point point = button.getLocation();
final Insets margin = button.getMargin();
final int delay = 75;
Runnable r = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 30; i++) {
try {
if (shakeWholeButton) {
moveButton(new Point(point.x + 5, point.y));
Thread.sleep(delay);
moveButton(point);
Thread.sleep(delay);
moveButton(new Point(point.x - 5, point.y));
Thread.sleep(delay);
moveButton(point);
Thread.sleep(delay);
} else {// text only
setButtonMargin(new Insets(margin.top, margin.left + 3, margin.bottom, margin.right - 2));
Thread.sleep(delay);
setButtonMargin(margin);
Thread.sleep(delay);
setButtonMargin(new Insets(margin.top, margin.left - 2, margin.bottom, margin.right + 3));
Thread.sleep(delay);
setButtonMargin(margin);
Thread.sleep(delay);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
};
Thread t = new Thread(r);
t.start();
}
private void moveButton(final Point p) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
button.setLocation(p);
}
});
}
private void setButtonMargin(final Insets margin) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
button.setMargin(margin);
}
});
}
}