2011-10-17 26 views
2

我有一個應用程序在JTable上有羊條目。通過從JTable的父母id列的JComboBox編輯器中選擇一個ID,可以將綿羊製成其他綿羊的孩子。要做到這一點,父母身份號碼JComboBox必須掃描其他綿羊的ID,並按預期消除其中的一些,並將它們一起顯示在其popup中。SwingWorker和JComboBox

這不是一個耗時的過程;但在我看來,如果羊數量增加,那麼它可能會導致GUI變得沒有反應。這就是爲什麼我想在掃描過程中使用SwingWorker。如果它掃描doInBackground方法中的ID並將這些ID返回到done方法將會很好。

所以JComboBox會顯示任何可能的父母ids。雖然doInBackground方法在done方法效果很好,當我添加一個數字到JComboBox,我想這使得popup變得不可見。

正因爲如此,每當我點擊父的細胞的ID JComboBox pupup出現並迅速消失,而不顯示任何父標識。但它必須顯示父母ID。有沒有辦法做到這一點?

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package sheepfarm.tools; 

import java.awt.Component; 
import java.awt.event.ItemEvent; 
import java.awt.event.ItemListener; 
import java.util.ArrayList; 
import java.util.Vector; 
import java.util.concurrent.ExecutionException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.AbstractCellEditor; 
import javax.swing.JComboBox; 
import javax.swing.JTable; 
import javax.swing.event.PopupMenuEvent; 
import javax.swing.event.PopupMenuListener; 
import javax.swing.table.TableCellEditor; 
import org.joda.time.Interval; 
import java.util.Date; 
import javax.swing.DefaultComboBoxModel; 
import javax.swing.SwingWorker; 

/** 
* 
* @author Personal Computer 
*/ 
public class JParentIDCellEditor extends AbstractCellEditor implements TableCellEditor { 

    private JComboBox jComboBox = new JComboBox(); 
    private boolean cellEditingStopped = false; 

    @Override 
    public Object getCellEditorValue() { 
     return jComboBox.getSelectedItem(); 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
     ArrayList<Integer> arrayList = new ArrayList<Integer>(); 
     arrayList.add(Integer.parseInt(value.toString())); 

     jComboBox = new JComboBox(); 
     ParentIDCellWorker worker = new ParentIDCellWorker(table, jComboBox, row, value); 
     worker.execute(); 

     jComboBox.addItemListener(new ItemListener() { 

      @Override 
      public void itemStateChanged(ItemEvent e) { 
       if (e.getStateChange() == ItemEvent.SELECTED) { 
        fireEditingStopped(); 
       } 
      } 
     }); 
     jComboBox.addPopupMenuListener(new PopupMenuListener() { 

      @Override 
      public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 
       cellEditingStopped = false; 
      } 

      @Override 
      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 
       cellEditingStopped = true; 
       fireEditingCanceled(); 

      } 

      @Override 
      public void popupMenuCanceled(PopupMenuEvent e) { 
      } 
     }); 
     return jComboBox; 
    } 

    public class ParentIDCellWorker extends SwingWorker<Vector, Vector> { 

     private JTable table; 
     private JComboBox jComboBox; 
     private int row; 
     private Object value; 

     public ParentIDCellWorker(JTable table, JComboBox jComboBox, int row, Object value) { 
      this.table = table; 
      this.jComboBox = jComboBox; 
      this.row = row; 
      this.value = value; 
     } 

     @Override 
     protected Vector doInBackground() throws Exception { 
      Vector vector = new Vector(); 
      vector.add(0); 
      for (int i = 0; i < table.getRowCount(); i++) { 
       try { 
        Interval interval = new Interval(((Date) table.getValueAt(i, 2)).getTime(), new Date().getTime()); 
        interval = new Interval(((Date) table.getValueAt(i, 2)).getTime(), ((Date) table.getValueAt(row, 2)).getTime()); 
        String gender = table.getValueAt(i, 3).toString(); 
        if (!vector.contains(table.getValueAt(i, 0)) && gender.equals("Sheep")) { 
         vector.add(table.getValueAt(i, 0)); 
        } 
       } catch (IllegalArgumentException exp) { 
       } 
      } 
      String[] rowsToRemove = getChildren(Integer.parseInt(table.getValueAt(row, 0).toString()), table).split("-"); 
      for (int i = 0; i < rowsToRemove.length; i++) { 
       vector.removeElement((Object) (Integer.parseInt(rowsToRemove[i]))); 
      } 
      return vector; 
     } 

     public String getChildren(int id, JTable jTable) { 
      String id_map = ""; 
      for (int i = 0; i < jTable.getRowCount(); i++) { 
       if (Integer.parseInt(jTable.getValueAt(i, 1).toString()) == id) { 
        id_map += getChildren(Integer.parseInt(jTable.getValueAt(i, 0).toString()), jTable); 
       } 
      } 
      return id + "-" + id_map; 
     } 

     @Override 
     protected void done() { 
      try { 
       for (Object i : get()) { 
        jComboBox.addItem(i); 

       } 
       jComboBox.setSelectedItem(value); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(JParentIDCellEditor.class.getName()).log(Level.SEVERE, null, ex); 
      } catch (ExecutionException ex) { 
       Logger.getLogger(JParentIDCellEditor.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 

    @Override 
    public boolean stopCellEditing() { 
     return cellEditingStopped; 
    } 
} 
+0

@MOD你是在JTable中的這種邏輯意義http://stackoverflow.com/questions/6246005/jcombobox-change-another-jcombobox/6246655#6246655 – mKorbel

+0

kindda。我想讓組合框在swing工作器中進行計算,以顯示影響值,並在完成計算後在其彈出窗口中顯示值。但在計算完成後,當我把值放入組合框時,打開的彈出窗口關閉。所以我不能顯示組合框中的計算值。彈出窗口應該等到所有的值都被放入它並且usere選擇一個 – MOD

回答

1

我不確定,但等到用戶點擊彈出窗口時可能已經太晚了。相反,你可以啓動一個SwingWorker創建List<ComboBoxModel>getTableCellEditorComponent被調用,也許當你構建父表的模型。這樣,您的getTableCellEditorComponent方法可以爲該行設置正確的模型。我想你將不得不在編輯器中保持List的最新狀態,但這似乎更容易。