2011-10-27 4 views
4

私は、最後の列(チェックボックスとして表示)にいくつかのブール値を持つカスタムDefaultTableModelを使ってJTableを持っています。setValueAtを使用して相互排他的なチェックボックスを再作成

クリックした値を取得するためにMouseListenerを追加すると、目盛りボックスのトグルが行われなくなったように見えます。

// As soon as this is used in the component 
// that is using the JTable, the toggling stops 
table.addMouseListener(new MouseAdapter() { 
      public void mouseClicked(MouseEvent evt) { 
       int col = table.getSelectedColumn(); 
       int row = table.getSelectedRow(); 

       Object o = table.getModel().getValueAt(row, col); 

私は、イベントリスナーによって消費されていることを前提としています。トグル動作を復元するためにMouseListenerコードに何を追加できますか?

編集:

おっと、問題は私のオーバーライドであることが表示されます:

@Override 
public void setValueAt(Object aValue, int row, int column) { 

    // Attempt at mutually exclusive checkboxes 
    if(column == 2){ // Starts at 0. Seek an alternative solution to avoid hardcoding? 
     // Algorithm: cycle through List to set other Booleans to false 

     // Uses entities. Is there another way of getting the number of rows from model? 
     List<MyEntity> myEntities = this.getDatas(); 

     for(int i = 0; i < myEntities.size(); i++){ 
      if(i != row){ 
       // Make sure this calls parent 
       super.setValueAt(false , i, 2); 
      } 
     } 

    } else { 
     super.setValueAt(aValue, row, column); // Call parent class 
    } 

} 
+0

あなたはテーブルセルから値を取得する必要がある理由、あなたの質問に本当の答えのためにあなたはhttp://sscce.org/ – mKorbel

+0

@mKorbelを投稿する必要があります:私は投稿してみたいですいくつかの簡潔なコードがいくつかの依存関係があります。ブール値を表す列をクリック - >クリックされたブール値をtrueに設定(チェックボックスをオンにする) - >列内の他のすべてのブール値を相互排除のためにfalseに設定 - >チェックボックスの1つがチェックされている場合、JButtonを有効にします。 –

+0

実際に実装する必要があるものが不明な場合は、非常に簡単な方法と1つ2つの最も複雑な方法がありますが、どれがMVCモデルに適しているかを確認してください。 – mKorbel

答えて

10

MouseListenerあなた自身を追加しないでください。代わりにのsetValueAt()を上書きすると、デフォルトのエディタで設定された新しい値がBoolean.classになります。

補足:ここにはsscceがあります。便宜のために、単にCHECK_COLのすべてのエントリをクリアし、新しい値を設定し、それに応じてボタンを調整します。

CheckOne image

import java.awt.*; 
import javax.swing.*; 
import javax.swing.table.DefaultTableModel; 

/** 
* @see http://stackoverflow.com/questions/7920068 
* @see http://stackoverflow.com/questions/4526779 
*/ 
public class CheckOne extends JPanel { 

    private static final int CHECK_COL = 1; 
    private static final Object[][] DATA = { 
     {"One", Boolean.FALSE}, {"Two", Boolean.FALSE}, 
     {"Three", Boolean.FALSE}, {"Four", Boolean.FALSE}, 
     {"Five", Boolean.FALSE}, {"Six", Boolean.FALSE}, 
     {"Seven", Boolean.FALSE}, {"Eight", Boolean.FALSE}, 
     {"Nine", Boolean.FALSE}, {"Ten", Boolean.FALSE}}; 
    private static final String[] COLUMNS = {"Number", "CheckBox"}; 
    private DataModel dataModel = new DataModel(DATA, COLUMNS); 
    private JTable table = new JTable(dataModel); 
    private ControlPanel cp = new ControlPanel(); 

    public CheckOne() { 
     super(new BorderLayout()); 
     this.add(new JScrollPane(table)); 
     this.add(cp, BorderLayout.SOUTH); 
     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     table.setPreferredScrollableViewportSize(new Dimension(250, 175)); 
    } 

    private class DataModel extends DefaultTableModel { 

     public DataModel(Object[][] data, Object[] columnNames) { 
      super(data, columnNames); 
     } 

     @Override 
     public void setValueAt(Object aValue, int row, int col) { 
      if (col == CHECK_COL) { 
       for (int r = 0; r < getRowCount(); r++) { 
        super.setValueAt(false, r, CHECK_COL); 
       } 
      } 
      super.setValueAt(aValue, row, col); 
      cp.button.setEnabled(any()); 
     } 

     private boolean any() { 
      boolean result = false; 
      for (int r = 0; r < getRowCount(); r++) { 
       Boolean b = (Boolean) getValueAt(r, CHECK_COL); 
       result |= b; 
      } 
      return result; 
     } 

     @Override 
     public Class<?> getColumnClass(int col) { 
      if (col == CHECK_COL) { 
       return getValueAt(0, CHECK_COL).getClass(); 
      } 
      return super.getColumnClass(col); 
     } 

     @Override 
     public boolean isCellEditable(int row, int col) { 
      return col == CHECK_COL; 
     } 
    } 

    private class ControlPanel extends JPanel { 

     JButton button = new JButton("Button"); 

     public ControlPanel() { 
      button.setEnabled(false); 
      this.add(new JLabel("Selection:")); 
      this.add(button); 
     } 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("CheckOne"); 
     frame.add(new CheckOne()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

'setValueAt()'をオーバーライドしただけです。しかし、私の論理に欠陥があるに違いない。私がしたいのは、一度に一つのチェックボックスだけをアクティブにするか、 'setValueAt()'を私のGenericTableModelに渡すことです。 私が 'MouseListener'を使用するのは、1つのティックボックスがチェックされている(ブール値の1つが真である)場合にJButtonをアクティブにしたいからです。 –

+1

私は上記の1つのアプローチを示しました。 – trashgod

+0

'JRadioButton'を使ったアプローチが表示されています[here](http://stackoverflow.com/a/11259671/230513)。 – trashgod

関連する問題