2017-10-10 1 views
1
거짓

나는 현재이 TableModel에의 관련 방법이다의 TableModel setCellEditable와 자동으로

@Override 
public void actionPerformed(ActionEvent e){ 
    if(e.getActionCommand() == "Unlock"){ 
     pTableModel.setCellEditable(this.getSelectedRow(), this.getSelectedColumn(), true); 
    } 
} 

를 사용하여 편집을 위해 셀의 잠금 해제를 할 수 있습니다 내 JTable의에 JPopupMenu를 구현하기 위해 노력하고있어에 대한 값을 설정

public void setCellEditable(int row, int col, boolean value) { 
    editableCells[row][col] = value; 
    this.fireTableCellUpdated(row, col); // I don't think I actually need this 
             //because nothing in the cell has changed yet? 
} 

isCellEditable() 다음 editableCells [] [] 어레이의 값을 반환한다. 하지만 포커스가 끊어지면 내 코드에서 셀을 편집 가능하지 않게 변경해야합니까?

약간 관련있는 메모에서 셀을 즉시 얻고 싶습니다. 나는 getEditorComponent().requestFocus()에 대해 읽었습니다. 그러나 그 때 편집되는 것이 없기 때문에 셀이 제대로 선택되지 않았습니다. (그 방법을 사용하면 내 생각 프로세스를 지원하는 것처럼 보이는 nullpointerexception이 발생합니다.)

누구나 올바른 방향으로 나를 가리킬 수 있습니까? 내가 어디로 잘못 가고 있는지 나는 볼 수 없다. 감사합니다

** 편집 :

private class CustomCellRenderer extends DefaultTableCellRenderer{ 
    public CustomCellRenderer(){ 
     addFocusListener(new FocusAdapter(){ 
      @Override 
      public void focusLost(FocusEvent e) { 
       pTableModel.setCellEditable(getSelectedRow(), getSelectedColumn(), false); 

      } 
     }); 
    } 
} 

하지만이 중 하나가 작동 듯하지 않은,하지만 난 아마 구현 해요 : 초점은 내가하는 focusListener와 사용자 정의 CellRenderer를 추가하는 시도 손실 된 경우 셀을 잠그는 그것은 잘못


SSCCE (내가 확인했습니다 있지만 렌더러 추가 ​​된 것을)

import java.awt.event.*; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.table.AbstractTableModel; 

public class CellTest {  
    public static void main(String[] args){ 
     SwingUtilities.invokeLater(new Runnable(){ 
      @Override 
      public void run(){ 
       createAndShowGUI(); 
      } 
     }); 
    } 
    private static void createAndShowGUI(){ 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     MyPanel panel = new MyPanel(); 

     f.add(panel); 
     f.pack(); 
     f.setVisible(true); 
    } 
} 


class MyPanel extends JPanel implements ActionListener{ 
    private JTable table; 
    private MyTableModel model; 
    private JScrollPane sp; 
    private List<Person> people; 

    MyPanel(){ 
     people = new ArrayList<>(); 
     people.add(new Person("Will", 1)); 
     model = new MyTableModel(people); 

     table = new JTable(model); 
     table.addMouseListener(new MouseAdapter(){ 
      @Override 
      public void mousePressed(MouseEvent e){ 
       maybeShowPopup(e); 
      } 
      @Override 
      public void mouseReleased(MouseEvent e){ 
       maybeShowPopup(e); 
      } 
     }); 

     table.setFillsViewportHeight(true); 
     sp = new JScrollPane(table); 
     this.add(sp); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e){ 
     if(e.getActionCommand().equals("Unlock")) { 
       model.setCellEditable(table.getSelectedRow(),table.getSelectedColumn(),true); 
     } 
    } 

    private JPopupMenu createPopupMenu(){ 
     JPopupMenu pop = new JPopupMenu(); 
     JMenuItem item = new JMenuItem("Unlock"); 
     item.addActionListener(this); 
     pop.add(item); 
     return pop; 
    } 

    private void maybeShowPopup(MouseEvent e){ 
     int currentRow = table.rowAtPoint(e.getPoint()); 
     if(currentRow >= 0 && currentRow < table.getRowCount()) 
      table.setRowSelectionInterval(currentRow, currentRow); 
     else 
      table.clearSelection(); 

     if(table.getSelectedRow() < 0) return; 
     if(e.isPopupTrigger() && e.getComponent() instanceof JTable){ 
      JPopupMenu pop = createPopupMenu(); 
      pop.show(e.getComponent(), e.getX(), e.getY()); 
     } 
    } 
} 

그리고의 TableModel 및 데이터 클래스 : 길이에 대한

class MyTableModel extends AbstractTableModel{ 
    private List<Person> data; 
    private String[] colNames = new String[]{"Name","Age"}; 
    private boolean[][] editableCells; 

    public MyTableModel(List<Person> data){ 
     this.data = data; 
     this.editableCells = new boolean[this.getRowCount()][this.getColumnCount()]; 
    } 

    @Override 
    public int getRowCount() { return data.size(); } 

    @Override 
    public int getColumnCount() { return colNames.length; } 

    @Override 
    public Object getValueAt(int row, int col){ 
     Person p = data.get(row); 
     switch(col){ 
      case 0 : return p.getName(); 
      case 1 : return p.getAge(); 
     } 
     return null; 
    } 

    @Override 
    public boolean isCellEditable(int row, int col){ 
     return editableCells[row][col]; 
    } 

    public void setCellEditable(int row, int col, boolean value){ 
     editableCells[row][col] = value; 
    } 

    @Override 
    public void setValueAt(Object value, int row, int col){ 
     Person p = data.get(row); 
     switch(col){ 
      case 0 : p.setName((String)value);break; 
      case 1 : p.setAge((int)value);break; 
     } 
     this.setCellEditable(row, col, false); 
     this.fireTableCellUpdated(row, col); 
    } 

    public void setData(List<Person> data){ 
     this.data = data; 
     this.fireTableDataChanged(); 
    } 
} 

class Person { 
    private String name; 
    private int age; 

    public Person(String name, int age){ 
     this.name = name; 
     this.age = age; 
    } 

    public void setName(String name){ this.name = name;} 
    public String getName(){ return name; } 
    public void setAge(int age){ this.age = age;} 
    public int getAge(){ return age; } 
} 

사과 - 나는 아마도 가난 내가 달성하기 위해 원하는 것을 다시없이 짧게 만드는 방법을 알고하지 않았다. 이 코드에서 마우스 오른쪽 버튼을 클릭하고 '잠금 해제'를 클릭하면 실수로 이미 행을 왼쪽 버튼으로 클릭해야합니다. 그렇지 않으면 arrayIndexOutOfBounds 예외가 발생합니다. 정확한 원인을 아직 찾지 못했습니다.

기본적으로 마우스 오른쪽 버튼을 클릭하고 잠금 해제를 선택하면 커서가 셀에 나타나기를 원합니다. 현재 잠금 해제를 클릭 한 다음 셀을 두 번 클릭해야합니다.

+0

렌더러는 실제 구성 요소가 아닙니다. 이것은 컴포넌트의 이미지를 페인트하기 위해 사용됩니다. 그것은 결코 초점을 얻지 못할 것입니다. "=="를 사용하여 문자열을 비교하지 마십시오. 'equals (...) '메서드를 사용하십시오. 문제를 나타내는 적절한 [mcve]를 게시하십시오. – camickr

+0

미안하지만 그렇게 미미한 것은 아니지만 내가 달성하고자하는 것에 대한 설명과 함께 완전히 작동하는 예제를 게시했습니다. 덕분에 – NickW

답변

0

하지만 내 코드에서 초점을 잃을 때 편집 할 수없는 셀을 다시 변경해야합니까? -

당신 수 :

  1. 재정의 데이터가 변경되면 셀이 편집 할 수 있도록 귀하의 TableModel의 setValueAt(...) 방법.

  2. 사용 TableModelListener 셀의 데이터가 업데이트 될 때 이벤트를 생성합니다.

+0

. 감사합니다. setValueAt()에 넣으면 완벽하게 작동합니다. setCellEditable()은 fireTableCellUpdated()를 호출하기 때문에 무한 루프가 없으면 거기에 넣을 수 있다고 생각하지 않지만 SSCCE가 없으면 주석을 달 수 없다는 것을 이해합니다. 어쨌든 이제는 작동 중입니다. 다시 한 번 감사드립니다. – NickW

+0

이 답변을 표시하기 바로 전에 - 셀을 즉시 편집 가능하게 만드는 방법에 대한 아이디어가 있습니까? 즉, 셀을 마우스 오른쪽 버튼으로 클릭하고 '잠금 해제'를 선택하면 커서가 나타납니다. 나중에 다시 두 번 클릭하지 않아도됩니다. 도움이된다면 SSCCE를 만들 수 있습니다.하지만 나를 가리키는 막연한 방향이 있더라도 도움이됩니다. – NickW

+0

@NickW,'setCellEditable()은 fireTableCellUpdated()를 호출합니다 .' - 셀의 데이터가 변경되지 않았으므로 fireXXX() 메소드를 호출해서는 안됩니다. – camickr

관련 문제