2014-10-01 58 views
0

我遇到過這樣的問題。當我在容器上調用.revalidate時,我得到IndexOutOfBoundsException。Codename one container.revalidate()有時拋出IndexOutOfBoundsException

我有一個Runnable類,它增加或減少了組件邊距。我用它來製作一種抽屜動畫。除了這個例外,所有的東西都很完美。 Ans隨機拋出異常。在將此異常記錄到控制檯之前,我可以多次運行「動畫」方法。

之後,異常應用程序工作正常。只有容器顯示不正確。

這裏的錯誤日誌:

Exception in thread "Thread-15" java.lang.IndexOutOfBoundsException: Index: 5, Size: 1 
at java.util.ArrayList.rangeCheck(ArrayList.java:635) 
at java.util.ArrayList.get(ArrayList.java:411) 
at com.codename1.ui.Container.getComponentAt(Container.java:1083) 
at com.codename1.ui.Container.doLayout(Container.java:1054) 
at com.codename1.ui.Container.layoutContainer(Container.java:1043) 
at com.codename1.ui.Container.doLayout(Container.java:1056) 
at com.codename1.ui.Container.layoutContainer(Container.java:1043) 
at com.codename1.ui.Container.doLayout(Container.java:1056) 
at com.codename1.ui.Container.layoutContainer(Container.java:1043) 
at com.codename1.ui.Container.doLayout(Container.java:1056) 
at com.codename1.ui.Container.layoutContainer(Container.java:1043) 
at com.codename1.ui.Container.revalidate(Container.java:835) 
at util.classes.AnimationRunnable.run(AnimationRunnable.java:75) 
at java.lang.Thread.run(Thread.java:745) 

它爲什麼會這樣?可能是什麼問題?

謝謝!

UPD: 這是我運行的類:

刪除了不必要的代碼:

public class AnimationRunnable implements Runnable { 
private float marginFrom = 0; 
private float marginTo = 0; 
private Container bottomContainer; 
private int screenHeight; 

public AnimationRunnable(Container bottomContainer, int screenHeight, float marginFrom, float marginTo) { 
    this.marginFrom = marginFrom; 
    this.marginTo = marginTo; 
    this.bottomContainer = bottomContainer; 
    this.screenHeight = screenHeight; 
} 

@Override 
public void run() { 
    boolean finished = false; 
    boolean directionUp = marginFrom > marginTo; // true = up; false = down 
    Container parent = bottomContainer.getParent(); 

    while (!finished) { 
    // if distance between current margin and destination margin is < 10, finish 
     if (Math.abs(marginFrom - marginTo) < 10) { 
      finished = true; 
     } else { 
      // if container size is increasing 
      if (directionUp) { 
       // if current margin is less than destination margin 
       if (marginFrom <= marginTo) { 
        marginFrom = marginTo; 
        finished = true; 
       } else { 
       // else - modify current margin to be closer to destination margin 
        marginFrom -= Math.ceil((marginFrom - marginTo)/6); 
       } 
      } else { 
       // if current margin is less than destination margin 
       if (marginFrom >= marginTo) { 
        marginFrom = marginTo; 
        finished = true; 
       } else { 
       // else - modify current margin to be closer to destination margin 
        marginFrom += Math.ceil((marginTo - marginFrom)/6); 
       } 
      } 
     } 

     // Setting style to container (in case if container's current style is changed) 
     Style defaultStyle = bottomContainer.getStyle(); 
     bottomContainer.getStyle().setMargin(Component.TOP, Math.round(marginFrom)); 
     // Setting default style to all container states 

     // HERE EXCEPTION IS THROWN 
     // Revalidating either parent, or container itself 
     if (parent != null) { 
      parent.revalidate(); 
      parent.repaint(); 
     } else { 
      bottomContainer.revalidate(); 
      bottomContainer.repaint(); 
     } 

     try { 
     // Wait 25ms to make animation smooth 
      Thread.sleep(25); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    // revalidate once more after loop is over 
    if (parent != null) { 
     parent.revalidate(); 
     parent.repaint(); 
    } else { 
     bottomContainer.revalidate(); 
     bottomContainer.repaint(); 
    } 
    return; 
} 
} 

UPDATE

的callSerially不顯示動畫,它只是等待,並更新UI ,當動畫可運行時。但調用Display.geInstance()。invokeAndBlock()這個動畫runnable可以像通緝一樣工作而不會拋出異常。

+1

如需要幫助請輸入代碼 – CocoNess 2014-10-01 10:33:39

+0

當然!添加了我的代碼。 – NonGrate 2014-10-01 10:51:45

回答

2

您正在更改UI而不是EDT,這會導致您正在運行的線程和EDT(Event Dispatch線程)之間出現問題和衝突。

+0

有解決方案如何避免這些衝突,仍然使用單獨的線程來更改UI? – NonGrate 2014-10-01 12:47:18

+0

更改UI時使用callSerial。這裏有一個開發者指南部分。 – 2014-10-02 03:55:06