2017-10-18 281 views
-2

我試圖建立一個方法「移動()」,我可以使用frame.setLocation(int x,int y)方法移動JFrame時從開始到結束位置的動畫方式。我嘗試了以下方法,並將框架放在正確的位置,但問題在於動畫首先在x軸上下移,然後才沿y軸下移,但我的目標是使它看起來像是一個對角線運動目的地點。我知道它是因爲第一個forloop,因爲他們沒有合適的條件將setLocation方法的過程分解爲單個部分,但我完全不知道如何解決這個問題。與使用setLocation()「傳送」它的方式相比,如何更順利地將JFrame移動到特定位置?

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

預先感謝您!

+1

Swing是單線程,您需要將'for-loop'移出主線程。 Swing也不是線程安全的,所以任何對UI狀態的修改應該在主(Event Dispatching)線程的上下文中完成 - catch 22 - 最簡單的解決方案是使用Swing Timer。 – MadProgrammer

+0

可能的[有沒有辦法在Java中動畫整個Jframe,以便它移動?](https://stackoverflow.com/questions/14950694/is-there-a-way-to-animate-an-entire-jframe-in- java-so-it-it) – BaSsGaz

回答

2

Swing是單線程,您需要將for-loop從主線程移出。鞦韆也不是線程安全的,所以任何修改UI的狀態應的範圍內完成主(事件調度)線程 - 捕22 - 最簡單的解決方法是使用一個Swing 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(); 
    } 

} 
+0

非常感謝您的快速解決方案。我嘗試了你的代碼,它完美的工作。現在我真的必須閱讀很多關於你使用的東西,因爲我不瞭解它,並認爲實現我的想法會容易得多。 – NarcatasCor

+0

@NarcatasCor Swing中的動畫並不難,但它需要不同的方法和思維方式 – MadProgrammer

-1

您的第二個循環一直運行,直到完成,您需要同時移動框架,並且只在需要時增加XY

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++; 
    } 
} 
+0

這就是我已經嘗試過的,儘管這種情況下的動畫會以一種診斷方式移動窗口,但最終的位置將是錯誤的。 – NarcatasCor

+0

這仍然會阻塞事件調度線程,導致OP正在經歷的結果沒有變化 – MadProgrammer

+0

@MadProgrammer但他清楚地表示「動畫首先在x軸上下移,然後才沿y軸下移」這意味着他注意到動畫,所以我猜他沒有從主線程啓動它,這不是他真正的問題!爲什麼我會修理一些沒有損壞的東西! – BaSsGaz

相關問題