JPanel setLocation

其中说: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()); } } } 

通过调用Thread.sleep ,您可能会阻止事件调度线程,该线程负责处理绘制请求等。 这意味着在您的循环实际完成之前,EDT将无法处理面板的更新位置。

相反,使用javax.swing.Timer

查看Swing中的Concurrency以获取更多详细信息

更新

这是在FlowLayout btw下,所以我认为可能与它有关但不确定

您正在与布局管理器进行斗争,您会发现一旦revalidateusePanel正在使用的容器,它将重新定位到布局管理器想要组件的位置。

尝试查看Sliding-Layout以获得更好的解决方案

更新了一个基本示例

动画是随着时间的推移变化的幻觉。 在更新UI时,Swing对开发人员提出了一些相当严格的要求。

除了布局管理器之外,Swing还要求对UI的所有交互和修改都在事件调度线程的上下文中完成。 它还要求在EDT以外的其他线程中执行任何长时间运行或块处理。

这使我们陷入困境22.我们需要在后台运行,因此我们不会阻止EDT处理油漆请求(除其他事项外),但我们需要在EDT的上下文中更新我们的组件……

幸运的是,我们提供了许多解决方案。 最简单的问题是使用javax.swing.Timer

在此处输入图像描述

此示例使用根窗格的玻璃窗格function提供上覆滑出,有关详细信息,请参阅如何使用根窗格 。

它还使用可变定时动画。 也就是说,面板的位置基于动画的时间进度而不是某些固定的增量

 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(); } } } 

为什么你认为它不起作用? 可能你不能只注意到它。 在您的第一个setPosition()添加以下代码后:

 Thread.sleep(3000); 

然后你会注意到它。