2015-11-13 169 views
0

Pic防止JLabel職位重置?

在左側面板上我想我的JLabel左右移動的盒子內,並在右側面板我希望我的JLabel與當前時間頻繁更新,而盒子內走動,以隨機位置上的隨機位置以及。

我現在收到的問題是,當我設置JLabel的時間和位置時,我的JLabel在我的左邊框中出現了錯誤。在移動到它應該移動的隨機位置之前,它首先出現在初始位置(頂部)。

我有一個類實現了runnable,它處理左邊的JLabel,另一個類也實現了可隨時間更新處理JLabel的runnable。

任何人都可以幫我解決這個問題嗎?我希望通過這種方式來設置這個程序,其中兩個類實現可運行的JLabel移動的runnable。

這是左側面板,關心班級:

public class MoveDisplay { 
    private GUIFrame gui; 
    private boolean moving = true; 


    public MoveDisplay(GUIFrame gui) { 
     this.gui = gui; 
    } 

    public void start() { 
     moving = true; 
     Random rand = new Random(); 
     while (moving) { 
      int x = rand.nextInt(150) + 1; 
      int y = rand.nextInt(150) + 1; 

      java.awt.EventQueue.invokeLater(new Runnable() { 
        public void run() { 

         gui.moveDisplay(x, y, 100, 100); 
        } 
       }); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void stop() { 
     moving = false; 
    } 
} 

這是正確的面板,它是時鐘。

public class MoveClock { 
     private GUIFrame gui; 
     private boolean clock = true; 
     private volatile boolean running = true; 

     public MoveClock(GUIFrame gui) { 
      this.gui = gui; 
     } 

     public void start() { 
      clock = true; 
      Random rand = new Random(); 
      while (clock) { 

       Calendar cal = Calendar.getInstance(); 
        int hour = cal.get(Calendar.HOUR_OF_DAY); 
        int minute = cal.get(Calendar.MINUTE); 
        int second = cal.get(Calendar.SECOND); 
       gui.Klockan(hour, minute, second); 
        int a = rand.nextInt(100) + 1; 
        int b = rand.nextInt(100) + 1; 

        java.awt.EventQueue.invokeLater(new Runnable() { //Utan detta så kör inte Klockan random placeringar 
         public void run() { 

          gui.moveClock(a, b, 150, 150); 
         } 
        }); 


       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     public void stop() { 
      clock = false; 
     } 
    } 

而這正是所有的幀,Jpanels等類:

private JLabel movingDisplay; 
    private JLabel movingClock; 
    private MP3Player mp3_player; 
    private boolean playing = true; 
    private boolean moving = true; 
    private boolean clocking = true; 
// private Thread t1; 
    JDialog playingDialog; 
    private MoveDisplay moveDisplay; 
    private MoveClock moveClock; 

    Clip clip; 

    /** 
    * Starts the application 
    */ 
    public void Start() { 
     frame = new JFrame(); 
     frame.setBounds(0, 0, 494, 437); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     //frame.setLayout(null); 
     frame.setTitle("Multiple Thread Demonstrator"); 
     InitializeGUI(); // Fill in components 
     frame.setVisible(true); 
     frame.setResizable(false); // Prevent user from change size 
     frame.setLocationRelativeTo(null); // Start middle screen 
     moveDisplay = new MoveDisplay(this); 
     moveClock = new MoveClock(this); 
    } 

JPanel pnlDisplay = new JPanel(); 
     Border b2 = BorderFactory.createTitledBorder("Display Thread"); 
     pnlDisplay.setBorder(b2); 
     pnlDisplay.setBounds(12, 118, 222, 269); 
     pnlDisplay.setLayout(null); 

     // Add buttons and drawing panel to this panel 
     btnDisplay = new JButton("Start Display"); 
     btnDisplay.setBounds(10, 226, 121, 23); 
     pnlDisplay.add(btnDisplay); 

     btnDStop = new JButton("Stop"); 
     btnDStop.setBounds(135, 226, 75, 23); 
     pnlDisplay.add(btnDStop); 

     pnlMove = new JPanel(); 
     pnlMove.setBounds(10, 19, 200, 200); 
     Border b21 = BorderFactory.createLineBorder(Color.black); 
     pnlMove.setBorder(b21); 
     pnlDisplay.add(pnlMove); 
     // Then add this to main window 
     frame.add(pnlDisplay); 

     // The moving graphics outer panel 
     JPanel pnlTriangle = new JPanel(); 
     Border b3 = BorderFactory.createTitledBorder("Triangle Thread"); 
     pnlTriangle.setBorder(b3); 
     pnlTriangle.setBounds(240, 118, 222, 269); 
     pnlTriangle.setLayout(null); 

     // Add buttons and drawing panel to this panel 
     btnTriangle = new JButton("Start Rotate"); 
     btnTriangle.setBounds(10, 226, 121, 23); 
     pnlTriangle.add(btnTriangle); 

     btnTStop = new JButton("Stop"); 
     btnTStop.setBounds(135, 226, 75, 23); 
     pnlTriangle.add(btnTStop); 

     pnlRotate = new JPanel(); 
     pnlRotate.setBounds(10, 19, 200, 200); 
     Border b31 = BorderFactory.createLineBorder(Color.black); 
     pnlRotate.setBorder(b31); 
     pnlTriangle.add(pnlRotate); 
     // Add this to main window 
     frame.add(pnlTriangle); 



     movingDisplay = new JLabel("DisplayThread"); 
     pnlMove.add(movingDisplay); 
     btnDStop.setEnabled(false); 


     movingClock = new JLabel("TriangleThread"); 
     pnlRotate.add(movingClock); 
     btnTStop.setEnabled(false); 


     btnDisplay.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       moving = true; 
       btnDisplay.setEnabled(false); 
       btnDStop.setEnabled(true); 
       startMoveDisplay(); 
      } 
     }); 

     btnDStop.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       moving = false; 
       btnDisplay.setEnabled(true); 
       btnDStop.setEnabled(false); 
       startMoveDisplay(); 
      } 
     }); 

     btnTriangle.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       clocking = true; 
       btnTriangle.setEnabled(false); 
       btnTStop.setEnabled(true); 
       startMoveClock(); 
      } 
     }); 


    btnTStop.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      clocking = false; 
      btnTriangle.setEnabled(true); 
      btnTStop.setEnabled(false); 
      startMoveClock(); 
     } 
    }); 
} 

    public void startMoveDisplay() { 
     if(moving) { 
      new Thread(new Runnable() { 
       public void run() { 
        moveDisplay.start(); 
       } 
      }).start(); 
     } else { 
      moveDisplay.stop(); 
     } 
    } 

    public void startMoveClock() { 
     if(clocking) { 
      new Thread(new Runnable() { 
       public void run() { 
        moveClock.start(); 
       } 
      }).start(); 
     } else { 
      moveClock.stop(); 
     } 
    } 

    public void moveDisplay(int x, int y, int width, int height) { 
     movingDisplay.setBounds(x, y, width, height); 
    } 

    public void moveClock(int a, int b, int width, int height) { 
     movingClock.setBounds(a, b, width, height); 
    } 

    public void Klockan(int hour, int minute, int second) { 
     movingClock.setText(hour + ":" + minute + ":" + second); 
    } 
+1

我看到你的代碼在你的新問題工作正常:http://stackoverflow.com/questions/33710527/cant-set-image-in-jlabel-from-anywhere-except-jframe/33710599# 33710599。不要忘了單擊複選標記以「接受」答案,以便人們知道問題已解決。或者,如果您使用了不同的解決方案,請再次發佈自己的答案,以便人們知道問題已得到解決。請考慮使用論壇的人員,以便我們不花時間回答已有解決方案的問題。 – camickr

+0

@camickr我沒有注意到我在這裏回答。有了這個,我得到了我的問題排序,並得到了一切工作:)謝謝! – WeInThis

+0

你爲什麼要刪除你的其他問題?答案沒有幫助解決問題嗎? – camickr

回答

2

它出現在它的初始位置第一(盒的頂部)移動到它之前的隨機位置每它應該移動。

那麼,您的整個程序使用空佈局(這是不正確的,因爲Swing旨在與佈局管理器一起使用),除了添加隨機標籤的面板。

movingDisplay = new JLabel("DisplayThread"); 
    pnlMove.add(movingDisplay); 

這就是我不明白,你用pnlMove.setLayout(null)

所以我猜測佈局管理器暫時被調用,並且標籤在面板的開始處被繪製,然後它被移動到其隨機位置。

所以我的建議是:

  1. 不要構建使用空佈局(除了與隨機位置的面板)的圖形用戶界面。 Swing旨在與佈局經理一起使用。

  2. 不要使用Thread和Thread.sleep()。對於動畫使用擺動計時器。當Timer觸發時,代碼在EDT上執行,並且不需要SwingUtilities.invokeLater()。

  3. 所有你想要的代碼是改變標籤的位置,所以只需使用setLocation(...)方法,而不是setBounds()方法。

  4. 方法名稱不應以大寫字母開頭。你的大部分名字都是正確的。始終如一!請注意論壇如何突出顯示方法名稱,比如它們是類名稱?