代码之家  ›  专栏  ›  技术社区  ›  NarcatasCor

如何将JFrame移动到特定位置比使用setLocation()将其“传送”更平滑?

  •  -2
  • NarcatasCor  · 技术社区  · 7 年前

    public int currentX() {
        return (int) frame.getLocation().getX();
    }
    
    public int currentY() {
        return (int) frame.getLocation().getY();
    }
    
    public void move(int x, int y) {
        for (int newX = currentX(); newX < x; newX++) {
            frame.setLocation(currentX() + 1, currentY());
            for(int newY = currentY(); newY < y; newY++) {
                frame.setLocation(currentX(), currentY() + 1);
            }
        }
    }
    

    提前谢谢!

    2 回复  |  直到 7 年前
        1
  •  2
  •   MadProgrammer    7 年前

    Swing是单线程,您需要移动 for-loop Timer

    How to use Swing Timers 有关更多详细信息

    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new JLabel("Hello"));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
    
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            move(frame, 100, 100);
                        }
                    });
                }
            });
        }
    
        public static void move(JFrame frame, int deltaX, int deltaY) {
            int xMoveBy = deltaX > 0 ? 4 : -4;
            int yMoveBy = deltaY > 0 ? 4 : -4;
    
            int targetX = frame.getX() + deltaX;
            int targetY = frame.getY() + deltaY;
    
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int frameX = frame.getX();
                    int frameY = frame.getY();
                    if (deltaX > 0) {
                        frameX = Math.min(targetX, frameX + xMoveBy);
                    } else {
                        frameX = Math.max(targetX, frameX - xMoveBy);
                    }
                    if (deltaY > 0) {
                        frameY = Math.min(targetY, frameY + yMoveBy);
                    } else {
                        frameY = Math.max(targetY, frameY - yMoveBy);
                    }
    
                    frame.setLocation(frameX, frameY);
                    if (frameX == targetX && frameY == targetY) {
                        ((Timer)e.getSource()).stop();
                    }
                }
            });
            timer.start();
        }
    
    }
    
        2
  •  -1
  •   BaSsGaz    7 年前

    第二个循环一直运行到完成,您需要同时移动帧,并且只需增量 X Y 需要时!

    public int currentX() {
        return (int) frame.getLocation().getX();
    }
    
    public int currentY() {
        return (int) frame.getLocation().getY();
    }
    
    public void move(int x, int y) {
        for (int newX = currentX(), newY = currentY(); newX < x || newY < y;     ) {
            frame.setLocation(newX, newY);
            if (newX < x) newX++;
            if (newY < y) newY++;
        }
    }