2016-11-26 9 views
0

私は少し絵を動かしたいと思っています。これは、JLabelのImageIconです。私の計画はJButtonを押して、whileループを実行して、毎秒50px右に移動させることでした。JLabel does not move

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 



public class Game extends JFrame implements ActionListener{ 

JButton jbUUp; 
JButton jbUDw; 
JButton jbUSh; 


public static ImageIcon shot; 
public static ImageIcon spL; 
public static ImageIcon spR; 

public static JLabel LspL; 
public static JLabel LspR; 
public static JLabel Lshot; 

public static int shPosUser = 150; 
public static int shPosKI = 150; 
public static int shXPosUser = 180; 


Game(){setLayout(null); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setSize(1000, 500); 
     getContentPane().setBackground(Color.WHITE); 

     spR = new ImageIcon("src/spR.jpg"); 
     LspR = new JLabel(spR); 
     LspR.setSize(170, 170); 
     LspR.setLocation(820, shPosKI); 
     LspR.setVisible(true); 

     spL = new ImageIcon("src/spL.jpg"); 
     LspL = new JLabel(spL); 
     LspL.setSize(170, 170); 
     LspL.setLocation(10, shPosUser); 
     LspL.setVisible(true); 

     shot = new ImageIcon("src/shot.gif"); 
     Lshot = new JLabel(shot); 
     Lshot.setSize(21, 15); 
     Lshot.setLocation(shXPosUser, shPosUser + 77); 
     Lshot.setVisible(false); 

     jbUUp = new JButton("U"); 
     jbUUp.setSize(60, 30); 
     jbUUp.setLocation(10, 350); 
     jbUUp.addActionListener(this); 

     jbUDw = new JButton("D"); 
     jbUDw.setSize(60, 30); 
     jbUDw.setLocation(10, 420); 
     jbUDw.addActionListener(this); 

     jbUSh = new JButton("S"); 
     jbUSh.setSize(60, 30); 
     jbUSh.setLocation(10, 385); 
     jbUSh.addActionListener(this); 

     add(LspR); 
     add(LspL); 
     add(Lshot); 
     add(jbUUp); 
     add(jbUDw); 
     add(jbUSh); 
     } 

public void actionPerformed(ActionEvent e){if(e.getSource() == jbUUp){User.moveUp();} 

              if(e.getSource() == jbUDw){User.moveDown();} 

              if(e.getSource() == jbUSh){User.shot();} 
              } 





} 

これらは今、私の問題は、画像が動かないということである二つのクラス

public class User { 

User(){} 

public static void moveUp(){Game.shPosUser = Game.shPosUser - 10; 
          Game.LspL.setLocation(10, Game.shPosUser);} 

public static void moveDown(){Game.shPosUser = Game.shPosUser + 10; 
           Game.LspL.setLocation(10, Game.shPosUser);} 

public static void shot(){Game.Lshot.setVisible(true); 
          while(Game.shXPosUser < 500){timeout(1000); 
                 Game.shXPosUser = Game.shXPosUser + 50; 
                 System.out.println(Game.shXPosUser); 
                 Game.Lshot.setLocation(Game.shXPosUser, Game.shPosUser); 
                 } 
          Game.Lshot.setVisible(false); 
          Game.shXPosUser = 180; 
          Game.Lshot.setLocation(Game.shXPosUser, Game.shPosUser); 
          } 

public static void timeout(int time){try{Thread.sleep(time);} 
            catch(Exception e){} 
           } 

} 

です。座標は変更されますが、座標は再配置されません。

+0

*「私は小さな絵を動かしたいと思っていました。それはJLabelのImageIconです。私の計画は、JButtonを動かすwhileループを実行することでした。」*私は新しい計画を提案します。 'paintComponent(Graphics)'をオーバーライドする 'JPanel'の画像をカスタムペイントします。コンポーネントの周りを移動することは、アニメーションを推薦する方法ではありません。特に、画面上に複数のビジュアル要素をアニメートする場合は、上記のコードは、さまざまな画像を読み込みます。それらがnullレイアウトのコンポーネント内にある場合、オーバーラップするときの動作は定義されません。 (ここでレンダリングを完全に制御する理由の1つです) –

答えて

1

変更を表示するためにフレームを再描画する必要があるため、repaint()メソッドJFrameを呼び出してUIを更新してください。例えば

if(e.getSource() == jbUUp){ 
    User.moveUp(); 
    repaint(); 
} 

はそれがうまくいくと思います。

+0

理由はないので、repaint()を呼び出します。コンポーネントのプロパティ(setLocationなど)を変更すると、コンポーネントは自動的にそれ自体を再描画します()。 – camickr

1

JLabel は、です。画面が再描画されていないため、JLabelの新しい位置を表示することはできません。ゲームファイルのどこかで、repaint();に電話をかけて画面を再描画する必要があります。すべての

+0

また、ELITEが提案したことがうまくいくかどうかは分かりません。ユーザーが移動を終了するまで、whileループがスレッドの実行をブロックしていることを考慮すると、それまでは再ペイントは呼び出されないと考えられます。これを正常に再描画するには、whileループ内から再描画を呼び出す必要があります。 – EKW

+0

理由はありませんので、repaint()を呼び出してください。コンポーネントのプロパティ(setLocationなど)を変更すると、コンポーネントは自動的にそれ自体を再描画します()。 – camickr

1

まず:

  1. あなたが質問をするとき、ポストコードを正しくフォーマットされています。あなたのコードのインデントがすべての場所にあります。コードを読む時間がかかるようにしたい場合は、コードが読みやすいようにしてください。

  2. すべての静的変数を削除します。これは、staticキーワードの使用方法ではありません。

  3. Java命名規則に従ってください。変数名は大文字で始めるべきではありません。私の計画

はそれが正しい

あなたは、whileループを使用することはできませんに毎秒は50px移動whileループのウィッヒを実行するのJButtonを押すようにしました。ループ内のThread.sleep()は、ループの実行が終了するまでGUIが再描画されないようにします。この場合、最終位置にアイコンが表示されます。

解決策は、Swing Timerを使用することです。 Timerは、新しい場所を計算できるイベントを生成します。アニメーションを終了させるときは、タイマーを停止する必要があります。

詳細については、How to Use Swing TimersのSwingチュートリアルのセクションを参照してください。