其中说:usePanel.setLocation(800,usePanel.getY());它没有设置它刚刚从中间开始的位置,但是在for循环中逐渐改变位置以获得很酷的动画,它可以正常工作。
任何想法为什么第一个设置位置才能开始工作?这是在FlowLayout btw下,所以我认为可能与它有关但不确定。
usePanel.setLocation(800,usePanel.getY());
for(int x=0;x<3500;x+=6){
usePanel.setLocation(usePanel.getX()-5,usePanel.getY());
Thread.sleep(500);
}
更新了当前代码
private Timer nextloc;
private JPanel usePanel;
private static ClosePanel cp = new ClosePanel("null");
public void run(){
Timer andgo = new Timer(10,new TimerListener());
while(!cp.getCloseDone()){
andgo.start();
andgo.restart();
}
if(panel.equals("topiccreator")){
usePanel=topiccreator;
}else{
System.out.println("NULL PANEL TO MOVE!");
usePanel=mainmenu;
}
//This is what is not working
usePanel.setLocation(usePanel.getX()+800,usePanel.getY());
usePanel.setVisible(true);
nextloc = new Timer(50,new TimerListener());
for(int r=0;r<3500;r+=6){
nextloc.start();
nextloc.restart();
}
}
private class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e){
if(e.getSource()==nextloc){
usePanel.setLocation(usePanel.getX()-5,usePanel.getY());
}
}
}
答案 0 :(得分:2)
通过调用Thread.sleep
,您可能会阻止事件调度线程,该线程负责处理绘制请求等。这意味着在您的循环实际完成之前,EDT将无法处理面板的更新位置。
相反,请使用javax.swing.Timer
...
查看Concurrency in Swing了解详情
<强>更新强>
这是在FlowLayout btw下,所以我认为可能有事情要做 有它但不确定
你正在与布局管理器作斗争,你会发现,revalidate
正在使用的容器usePanel
后,它将重新定位到布局管理器想要组件的位置。
尝试查看Sliding-Layout以获得更好的解决方案
更新了基本示例
动画是随时间变化的幻觉。在更新UI时,Swing对开发人员提出了一些相当严格的要求。
除了布局管理器之外,Swing要求对UI的所有交互和修改都在事件调度线程的上下文中完成。它还要求在EDT以外的其他线程中执行任何长时间运行或块处理。
这使我们陷入困境22.我们需要在后台运行,因此我们不会阻止EDT处理绘图请求(以及其他内容),但我们需要在EDT的上下文中更新我们的组件...
幸运的是,我们提供了许多解决方案。最简单的问题是使用javax.swing.Timer
此示例使用根窗格的玻璃窗格功能提供覆盖的幻灯片,有关详细信息,请参阅How to use Root Panes。
它还使用可变定时动画。也就是说,面板的位置基于动画的时间进度而不是某些固定的增量
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class SlidingPane {
private SlidePane slidePane = new SlidePane();
public static void main(String[] args) {
new SlidingPane();
}
public SlidingPane() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JButton slideButton = new JButton("Slide");
slideButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
slidePane.slide();
}
});
JFrame frame = new JFrame("Testing");
JPanel glassPane = new JPanel(null);
glassPane.setOpaque(false);
glassPane.add(slidePane);
frame.setGlassPane(glassPane);
glassPane.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(new JLabel("Look ma, no hands!"), gbc);
frame.add(slideButton, gbc);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SlidePane extends JPanel {
private long startTime = -1;
private int runTime = 1000;
private int startX;
private int targetX;
private boolean slideIn = false;
private Timer slideTimer;
public SlidePane() {
setBackground(Color.DARK_GRAY);
setBorder(new LineBorder(Color.BLACK));
setLocation(-getPreferredSize().width, 0);
setLayout(new GridBagLayout());
JLabel label = new JLabel("I'm your overload");
label.setForeground(Color.WHITE);
add(label);
slideTimer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long diff = System.currentTimeMillis() - startTime;
double progress = (double)diff / (double)runTime;
if (progress >= 1d) {
progress = 1d;
slideTimer.stop();
startTime = -1;
}
Container parent = getParent();
int height = parent.getHeight();
setSize(getPreferredSize().width, height);
int x = calculateProgress(startX, targetX, progress);
setLocation(x, 0);
revalidate();
repaint();
}
});
}
protected int calculateProgress(int startValue, int endValue, double fraction) {
int value = 0;
int distance = endValue - startValue;
value = (int) Math.round((double) distance * fraction);
value += startValue;
return value;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 400);
}
public void slide() {
slideTimer.stop();
startTime = System.currentTimeMillis();
slideIn = !slideIn;
startX = getX();
targetX = 0;
if (!slideIn) {
targetX = -getPreferredSize().width;
}
slideTimer.start();
}
}
}
答案 1 :(得分:0)
为什么你认为它不起作用?可能你不能只注意到它。在您第一次setPosition()
添加以下代码后:
Thread.sleep(3000);
然后你会注意到它。