JPanel setLocation

时间:2013-09-29 21:16:16

标签: java swing location jpanel

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

2 个答案:

答案 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

enter image description here

此示例使用根窗格的玻璃窗格功能提供覆盖的幻灯片,有关详细信息,请参阅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);

然后你会注意到它。