2016-09-27 15 views
1

我正在嘗試做一些基本的Java,並且我的框架中有一個形狀。它使用JComponent類繪製形狀,並在頂部單擊按鈕時觸發動畫。直到for循環已經逃脫,重繪纔會發生,只有兩個框架

組件代碼只是此加入的JPanel

public void paintComponent(Graphics g){  
    Dimension dim = getSize();  
    g.setColor(Color.GREEN); 
    g.fillOval(margin, 150, 100, 100); 
    super.paintComponent(g); 
} 

動畫只是內部的做了循環,這只是編輯左邊距,以使圓形移動到右側;

​​3210

但它似乎沒有移動,直到循環結束,一次移動20個像素。我以前有一個睡眠功能,但它不動畫時似乎毫無意義。

任何見解?乾杯。

興趣的人,亂,很大程度上只是爲了讓造型全碼:

class Main extends JFrame{ 

public JPanel panel = new JPanel(); 
JButton button1 = new JButton("Move Right"); 

CreateComps cc = new CreateComps(); 

Main(){ 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    initUI(); 
} 

void initUI(){ 
    setSize(800,800); 
    setBackground(Color.GRAY); 
    setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS)); 

    JPanel topBar = new JPanel(); 
    topBar.setPreferredSize(new Dimension(800,30)); 
    topBar.setMaximumSize(new Dimension(800,30)); 
    topBar.setLayout(new BorderLayout()); 
    topBar.add(button1, BorderLayout.WEST); 
    topBar.setBackground(Color.GRAY); 

    JPanel container = new JPanel(); 
    container.setLayout(new GridBagLayout()); 
    container.setBackground(Color.DARK_GRAY); 

    panel.setPreferredSize(new Dimension(600,500)); 
    panel.setMinimumSize(new Dimension(600,500)); 
    panel.setBackground(Color.WHITE); 
    panel.setLayout(new BorderLayout()); 
    panel.add(cc, BorderLayout.CENTER); 

    add(topBar); 
    add(container); 
    container.add(panel); 

    Listener listen = new Listener(); 
    button1.addActionListener(listen); 

    setVisible(true); 
} 

public void reValidate(){ 
    panel.revalidate(); 
    panel.repaint(); 
} 

public static void main (String[] args){ 
    Main main = new Main(); 
} 

class Listener implements ActionListener{ 
    @Override 
    public void actionPerformed(ActionEvent e) { 

     System.out.println("Listening.."); 
     if(e.getSource().equals(button1)){ 
      int getMarg = cc.getMargin(); 
      for(int i = 1;i < 20;i++){ 
       getMarg = cc.getMargin(); 
       cc.setMargin(getMarg + 1);    
       reValidate(); 
       System.out.println(i); 
      } 
     }      
    } 
} 



} 

class CreateComps extends JComponent{ 

int margin = 10;   
public void setMargin(int marg){ 
    margin = marg; 
} 
public int getMargin(){ 
    return margin; 
} 
@Override 
public Dimension getPreferredSize(){ 
    return new Dimension(new Dimension(200,200)); 
} 
@Override 
public Dimension getMaximumSize(){ 
    return new Dimension(new Dimension(200,200)); 
} 
@Override 
public Dimension getMinimumSize(){ 
    return new Dimension(new Dimension(200,200)); 
} 
public void paintComponent(Graphics g){  
    Dimension dim = getSize();  
    g.setColor(Color.GREEN); 
    g.fillOval(margin, 150, 100, 100); 
    super.paintComponent(g); 
} 

}

回答

0

沒有停頓,你堆疊調用revalidate和會看到沒有別的比結果最後一次通話。

您之前擁有的睡眠功能,可能是在Event Dispatch Thread上調用的,因爲您阻止了整個事件調度和GUI更新,所以這並不好。

考慮或者使用另一個Threadsleep電話:

@Override 
public void actionPerformed(final ActionEvent e) { 

    System.out.println("Listening.."); 
    if (e.getSource().equals(button1)) { 
     new Thread() { 
      @Override 
      public void run() { 
       int getMarg = cc.getMargin(); 
       for (int i = 1; i < 20; i++) { 
        getMarg = cc.getMargin(); 
        cc.setMargin(getMarg + 1); 
        reValidate(); 
        System.out.println(i); 

        try { 
         Thread.sleep(50); 
        } catch (Throwable e) { 
        } 

       } 
      } 
     }.start(); 

    } 

} 

或者你也可以簡單地使用Timer,這是偉大的這份工作。

+1

非常感謝,標記爲答案。歡呼聲:) –

+0

儘管這確實說明了問題的核心(緊張/在美國東部時間睡覺),但我無法在這麼小的一段代碼中回答如此大量的不良做法。有一次,Swing中幾乎每個類都有'Swing不是線程安全的'。不要從非EDT線程調用'getMargin()'和'setMargin()'等。當你有方便的Swing'Timer'類時,爲什麼要創建一個全新的線程,它將直接在EDT上運行你的'Runnable'而不需要睡眠? – Ordous