2016-11-06 4 views
0

「아이템」클래스의 Vector 인 컨텐츠를 JTable로 취득합니다. 클래스 항목에는 문자열의 ArrayList 인 alt 필드를 제외하고 올바른 getter/setter가있는 숫자 및 영숫자 필드가 들어 있습니다. 이 칼럼에서는 comboBox 스타일 렌더러와 편집기를 사용하여 사용 가능한 선택 항목 중 하나를 선택하고 선택 항목을 표시하려고했습니다. alt 필드는 행마다 다르며 그로 인해 문제가 발생합니다. 나는이 렌더러에 대해 많은 예제를 보았지만 모든 예제에서 사용 가능한 선택 사항은 각 행마다 동일했습니다. 렌더러/편집기 클래스 마지막으로JTable로 combobox 형의 렌더러/에디터를 설정한다

public Class getColumnClass(int ci){ 
    if (ci==6) return JComboBox.class; 
    else return String.class;  
} 


@Override 
public void setValueAt(Object value, int rowIndex, int columnIndex) { 
    item it = data.get(rowIndex); 

    switch (columnIndex) { 
    case 0: 
     it.setNo((int) value); 
     break; 
    case 1: 
     it.setCode((int) value); 
     break; 
    case 2: 
     .... 
    case 6: 

     it.setAlt((List<String>) value); 
     break; 
    } 
} 

@Override 
public Object getValueAt(int rowIndex, int columnIndex) { 
    Object returnValue = null; 
    item it = data.get(rowIndex); 

    switch (columnIndex) { 
    case 0: 
     returnValue = it.getNo(); 
     break; 
    case 1: 
     returnValue = it.getCode(); 
     break; 
    case 2: 
     ... 
    case 6: 
     returnValue = it.getAlt(); 
     break; 
    } 

    return returnValue; 
}  

public boolean isCellEditable(int rowIndex, int columnIndex) { 
    return columnIndex > 0; 
} 

을 그리고 :

String[] sval = {"alfa", "Beta", "Gamma"}; //dummy array 

protected class ComboRenderer extends JComboBox implements TableCellRenderer { 

    public ComboRenderer(){ 
     super(sval);   //works, but this is not I want 
//  here should be used a similar super(list of options for a certain row), but how to get it? 
//  setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); 
     setOpaque(true); 
    } 


    public Component getTableCellRendererComponent(JTable table, Object value, 
      boolean isSelected, boolean hasFocus, int row, int column) { 

    if (isSelected) { 
       setForeground(table.getSelectionForeground()); 
       setBackground(table.getSelectionBackground()); 
     } else { 
       setForeground(table.getForeground()); 
       setBackground(table.getBackground()); 
     }   
     this.setSelectedItem(items); 
     return this; 
    } 

} 


protected class ComboEditor extends AbstractCellEditor 
implements TableCellEditor { 

    private List<String> alt; 

    protected ComboEditor() { 
     super(); 
    } 

    @Override 
    public Object getCellEditorValue() { 
     return this.alt; 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
     if (value instanceof List) { 
      this.alt = (List<String>) value; 
     } 

     JComboBox<String> combo = new JComboBox<String>(); 
    // combo.setEditable(true); //does not work for editable combobox! 
     for (String a : alt) { 
      combo.addItem(a); 
     } 

     combo.setSelectedItem(alt); 

     if (isSelected) { 
      setForeground(table.getSelectionForeground()); 
      setBackground(table.getSelectionBackground()); 
     } else { 
      setForeground(table.getForeground()); 
      setBackground(table.getBackground()); 
     }   

     return combo; 
    } 

} 

그리고 여기에 질문이

public class item extends Vector { 

private int no, code; 
private String ....; 
private List<String> alt; 

@SuppressWarnings("unchecked") 
public item(int no, int code, ...., List alt) { 
    super(); 
    this.add(no); 
    this.add(code); 
    .... 
    this.add(alt); 
} 

public int getNo() { 
    return (int) this.get(0); 
} 

public void setNo(int no) { 
    this.no = no; 
} 

// other setter/getters... 

public void setAlt(List<String> alt) { 
    this.alt = alt; 
} 

@SuppressWarnings("unchecked") 
public List<String> getAlt() { 
    return (List<String>) this.get(6); 
} 

@SuppressWarnings("all") 
public Vector getAsVector() { 
    // ArrayList<Object> a= new ArrayList<Object>(); 
    Vector a = new Vector(7); 
    a.add(no); 
    a.add(sifra); 
    a.add(red1); 
    a.add(red2); 
    a.add(sastojci); 
    a.add(eanKod); 
    a.add(alt); 
    return a; 
} 

}

JTable가 필요한 기능을 얻을 : 여기에 코드입니다 :

1) 렌더러는 생성자 중 잘못된 부분 (super (something))에 대해 분명히 작동하지 않습니다. 그러나이 부분에서는 렌더링 된 항목을 얻을 수 없으므로 초기화를위한 선택 목록을 얻을 수 없습니다. 그 문제를 해결하는 방법?

2) 편집기가 잘 작동하는 것처럼 보이지만 행에서 이동하면 이전 값이 다시 표시됩니다. 나는 여기서 어떻게해야 하는가? 새로운 데이터가 없으며이 항목에 사용할 수있는 옵션 중 하나만 선택하십시오.

3) 외부에서 특정 행에 대해 선택한 값에 도달하는 방법, 인쇄를 가정 해 봅시다.

4) 수정 대신 편집 가능한 Combobox를 가져 오는 방법은 무엇입니까? 라인

// combo.setEditable(true); //does not work for editable combobox! 

는 (. 어떤 제외 4) 한편

답변

0

내가 문제를 해결,이 경우에는 작동하지 않습니다하지만 난 그게 더 나은 해결책이 될 생각합니다, 그래서 난 여전히 다른 솔루션을 기다리고 있어요 . 처음 들어

, 난 상관없이, 너무 다른 모든 행에 대해 첫 번째 행의 선택을 반환하지 않습니다 하나 렌더러의 경우,

setSelectedItems(<available options>) 

의 반환 값을 가지고 있기 때문에이 선택한 어떤 것으로 나타났습니다 . 그래서 모든 행에 대해 하나의 렌더러 인스턴스를 만들기로 결정했습니다. 다음과 같이

rendererList = new ArrayList<ComboRenderer>(); 
.... 
// create the Array of renderers, one for each row 
    for (int cnt=0; cnt<data.size(); cnt++){ 
     ComboRenderer a = new ComboRenderer(); 
     a.setOptions(cnt); 
     rendererList.add(a); 
    } 
.... 
// telling to JTable which renderer to use for every cell  
@Override 
public TableCellRenderer getCellRenderer(int row, int coll) { 
    if (coll==6) return rendererList.get(row); 
    else return this.getDefaultRenderer(this.getColumnClass(coll));  

} 

렌더러 및 편집기 클래스가 지금 보일 것이다 : 즉, JTable의 생성자의 뜻은 다음과 같은 코드가 포함되어 있다는 것을 의미 지금 노력하고 있지만, 코드는 나에게 매우 서투른 보인다

protected class ComboRenderer extends JComboBox implements TableCellRenderer { 

    List<String> items; 
    int selected; 
    //selected will contains the index of selected option, changed through the cell editor as listener 

    public ComboRenderer(){ 
     super(); 
     setOpaque(true); 
     selected=0; //initial value 
    } 

    public void setSel(int k) { 
     selected=k; 
    } 

    public int getSel() { 
     return selected; 
    } 
    // filling each renderer with available options; 
    @SuppressWarnings("unchecked") 
    public void setOptions(int row) { 
     items = data.get(row).getAlt(); 

     for (String a : items) { 
      this.addItem(a); 
     } 
    } 

    public Component getTableCellRendererComponent(JTable table, Object value, 
      boolean isSelected, boolean hasFocus, int row, int column) { 

     if (isSelected) { 
       setForeground(table.getSelectionForeground()); 
       setBackground(table.getSelectionBackground()); 
     } else { 
       setForeground(table.getForeground()); 
       setBackground(table.getBackground()); 
     }  
     this.setSelectedIndex(selected); 
     return this; 
    } 

} 


class ComboEditor extends AbstractCellEditor implements TableCellEditor{ 

    private List<String> alt ; 


    protected ComboEditor() { 
     super(); 
    } 

    @Override 
    public Object getCellEditorValue() { 
     return this.alt; 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
     if (value instanceof List) { 
      this.alt = (List<String>) value; 
     } 

     JComboBox<String> combo = new JComboBox<String>(); 
     for (String a : alt) { 
      combo.addItem(a); 
     } 
     final ComboRenderer rend= rendererList.get(row); 
     // adding actionlistener to letting know the renderer the selection 
     combo.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       int i=((JComboBox<?>) arg0.getSource()).getSelectedIndex(); 
       // telling the renderer the selection  
       rend.setSel(i); 
      } 
     }); 

     combo.setSelectedIndex(rend.getSel()); 

     if (isSelected) { 
      setForeground(table.getSelectionForeground()); 
      setBackground(table.getSelectionBackground()); 
     } else { 
      setForeground(table.getForeground()); 
      setBackground(table.getBackground()); 
     }   

     return combo; 
    } 
} 

. 이 문제를보다 세련된 방법으로 해결할 수있는 방법이 있어야합니다. 나는 각 행마다 고유 한 렌더러가 있어야한다는 것을 믿을 수 없다. 이것은 메모리 낭비이다. 아무 생각 없어요?