簡體   English   中英

如果某些內容被另一類更改,如何使更改對一個類可見?

[英]How to make a change visible to one Class, if something was changed by another Class?

我試圖將JButton實現為線程,並且由於無法從線程返回JButton,所以我創建了一個新類AllButtons ,其中將所有JButton存儲在arrayList中。

問題是當我嘗試訪問Build類中的arrayList時,代碼給了我java.lang.IndexOutOfBoundsException異常。 但是,當我在ButtonThread類本身中訪問相同的ButtonThread時,它可以工作。

那么,考慮到已經將對象傳遞給ButtonThread構造函數,如何在BuildmyList中的更改可見?

AllButtons類,其中包含JButton的arrayList。

class AllButtons
{
   //new List
   List<JButton> myList = new ArrayList<JButton>();

   //add to List
   public void addMember(JButton button)
   {
     myList.add(button);
   } 

  //retrieve a particular value from List
   public JButton getButton(int index)
   {
     return myList.get(index);
   }

   //demo display
   public void display()
   {
     System.out.println(myList.get(0));
   }
}

將每個按鈕實現為線程

class ButtonThread implements Runnable
{
    Thread t;

    int red, green, blue, number = 0;
    int min = 0;
    int max = 255;
    AllButtons obj;

    ButtonThread(AllButtons obj, int number)
    {
       this.obj = obj;
       this.number = number;
       t = new Thread(this, "Color Thread" + this.number);
       t.start();
    }

    public void run()
    {
       red = rand();
       green = rand();
       blue = rand();
       JButton button = new JButton("button");
       changeColor(button, red, green, blue);

       this.obj.addMember(button);
       this.obj.display();  //debug //print Jbutton  // this works!!
    }

    int rand(){
      return ThreadLocalRandom.current().nextInt(min, max+1);
    }

    void changeColor(JButton btn, int red, int green, int blue)
    {
      btn.setBackground(new Color(red, green, blue));
    }

 }

班級建設

class Build
{
   //some code

   AllButtons ab = new AllButtons();

   Build()
   {

      /**
          JFrame code         **/

      //button

      new ButtonThread(ab, 1);  //make new button, object passed as well
      ab.display();  //here it fails,gives exception, list contains nothing, WHY ?

      JButton button1 = ab.getButton(0); //obviously this fails too


      /***********************/
      //JFrame Code//

   }
 }

我的猜測是您有比賽條件。 歡迎使用多線程!

請記住,一旦啟動第二個線程,該線程中將發生與主線程相關的操作時就沒有想法,除非您同步它們。

因此,可能發生的情況(IMO)是

  1. 您的構造函數調用t.start()(因此“ t”線程開始啟動)

...同時,您的代碼在主線程上繼續,因此

  1. 退出構造函數,返回Build方法
  2. 運行ab.display()(並由於ab為空而引發異常)
  3. 嘗試訪問ab [0](並拋出異常,因為為空)

...發生這種情況后,t線程終於啟動了,所以

  1. 運行並將其自身添加到ab。
  2. 成功運行ab.display()

正如上面提到的Gyro Gearless一樣,您確實需要閱讀Java中的同步和多線程技術。 這是發生錯誤的非常簡單的示例,但是當事情變得復雜時,除非您對如何保持線程安全有很好的了解,否則您將完全迷失方向。

Swing組件的處理應該由事件分發線程完成。 從另一個線程做某事,您將使用SwingUtilities.invokeLaterSwingUtilities.invokeAndWait

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM