2012-12-24 95 views
1

我想要一個JTable,它由2列(有RadioButton)有效和無效組成,因此如果有效列是Selected那麼無效無線按鈕得到Unselected,反之亦然意味着在單行中只能從2個單選按鈕中選擇1個單選按鈕。下面是單選按鈕的代碼。我無法爲這2列添加buttongroup。如何將JRadioButton添加到兩個JTable和ButtonGroup的組中。

public class NewJFrame extends javax.swing.JFrame { 
    DefaultTableModel dt; 
    public JRadioButton radioButton=new JRadioButton(); 


     public class RadioButtonCellEditorRenderer extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener { 



      public RadioButtonCellEditorRenderer() { 

       radioButton.addActionListener(this); 
       radioButton.setOpaque(false); 
      } 

      @Override 
      public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
       radioButton.setSelected(Boolean.TRUE.equals(value)); 
       return radioButton; 
      } 

      @Override 
      public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
       radioButton.setSelected(Boolean.TRUE.equals(value)); 
       return radioButton; 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       stopCellEditing(); 
      } 

      @Override 
      public Object getCellEditorValue() { 
       return radioButton.isSelected(); 
      } 

     } 

     public NewJFrame() { 
      initComponents(); 

      for(int i=0;i <10;i++) 
      { 


        //ButtonGroup bp[i]= new ButtonGroup(); 
      dt.addRow(new Object[]{null,false,false}); 


      } 
      // jTable1.setValueAt(false, 5, 1); 

     } 

     /** 
     * This method is called from within the constructor to initialize the form. 
     * WARNING: Do NOT modify this code. The content of this method is always 
     * regenerated by the Form Editor. 
     */ 
     @SuppressWarnings("unchecked") 
     // <editor-fold defaultstate="collapsed" desc="Generated Code"> 
     private void initComponents() { 

      buttonGroup1 = new javax.swing.ButtonGroup(); 
      jScrollPane4 = new javax.swing.JScrollPane(); 
      jTable1 = new javax.swing.JTable(); 

      setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

      dt= (new javax.swing.table.DefaultTableModel(new Object[][]{{null,null,null}},new String [] {"Name","Select", "Unselect"}) 
       { 
        Class[] types = new Class [] {java.lang.Integer.class,java.lang.String.class, java.lang.String.class}; 

        public Class getColumnClass(int columnIndex) { 
         return types [columnIndex]; 
        } 
        public boolean isCellEditable(int r,int c) 
        { 

         return true; 
        } 
       }); 

       //JTextField textBox= new JTextField(); 
       jTable1.setModel(dt); 
       TableColumn column = jTable1.getColumnModel().getColumn(1); 
       column.setCellEditor(new RadioButtonCellEditorRenderer()); 
       column.setCellRenderer(new RadioButtonCellEditorRenderer()); 
       TableColumn column1 = jTable1.getColumnModel().getColumn(2); 
       column1.setCellEditor(new RadioButtonCellEditorRenderer()); 
       column1.setCellRenderer(new RadioButtonCellEditorRenderer()); 
       jTable1.getTableHeader().setReorderingAllowed(false); 
       jScrollPane4.setViewportView(jTable1); 

       javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
       getContentPane().setLayout(layout); 
       layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
        .addGroup(layout.createSequentialGroup() 
         .addGap(12, 12, 12) 
         .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE) 
         .addContainerGap(13, Short.MAX_VALUE)) 
       ); 
       layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
        .addGroup(layout.createSequentialGroup() 
         .addGap(28, 28, 28) 
         .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 243, javax.swing.GroupLayout.PREFERRED_SIZE) 
         .addContainerGap(29, Short.MAX_VALUE)) 
       ); 

       pack(); 
      }// </editor-fold> 

     /** 
     * @param args the command line arguments 
     */ 
     public static void main(String args[]) { 
      /* Set the Nimbus look and feel */ 
      //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
      /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
      * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
      */ 
      try { 
       for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
        if ("Nimbus".equals(info.getName())) { 
         javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
         break; 
        } 
       } 
      } catch (ClassNotFoundException ex) { 
       java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } catch (InstantiationException ex) { 
       java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } catch (IllegalAccessException ex) { 
       java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
       java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } 
      //</editor-fold> 

      /* Create and display the form */ 
      java.awt.EventQueue.invokeLater(new Runnable() { 
       public void run() { 
        new NewJFrame().setVisible(true); 
       } 
      }); 
     } 

回答

7

這是我有一個示例代碼和我修改它並置於另一JRadioButton在塔2爲您的要求。第一列和第二列按行分組,如ButtonGroup。

輸出:

enter image description here

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.ItemEvent; 
import java.awt.event.ItemListener; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.DefaultCellEditor; 
import javax.swing.JButton; 
import javax.swing.JCheckBox; 
import javax.swing.JDialog; 
import javax.swing.JPanel; 
import javax.swing.JRadioButton; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.TableCellRenderer; 

/** Dialog class **/ 
public class DisplayTable extends JDialog { 
    public void initialize() { 

    SourceTableModel stm = new SourceTableModel(); 
    JTable sourceTable = new JTable(stm); 

    sourceTable.getColumnModel().getColumn(0).setCellRenderer(new RadioButtonRenderer()); 
    sourceTable.getColumnModel().getColumn(0).setCellEditor(new RadioButtonEditor(new JCheckBox())); 

sourceTable.getColumnModel().getColumn(1).setCellRenderer(new RadioButtonRenderer()); 
sourceTable.getColumnModel().getColumn(1).setCellEditor(new RadioButtonEditor(new JCheckBox())); 

JPanel panel = new JPanel(); 
panel.add(new JScrollPane(sourceTable)); 
add(panel, BorderLayout.CENTER); 

JPanel btnPanel = new JPanel(); 
JButton btnApply = new JButton("Close"); 
btnPanel.add(btnApply); 

btnApply.addActionListener(new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     System.exit(0); 
    } 
}); 

add(btnPanel, BorderLayout.SOUTH); 

setTitle("Radio Button in JTable Example"); 
setModal(true); 
pack(); 
setVisible(true); 
} 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      new DisplayTable().initialize(); 
     } 
    }); 
} 

} 

/** Table Model class for the Table **/ 
class SourceTableModel extends AbstractTableModel { 

private static final long serialVersionUID = 1L; 

private List<SourceModel> sourceList = new ArrayList<SourceModel>(); 
private String[] columnNamesList = {"Active", "InActive", "One", "Two"}; 

public SourceTableModel() { 
    this.sourceList = getSourceDOList(); 
} 

@Override 
public String getColumnName(int column) { 
    return columnNamesList[column]; 
} 

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

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

@Override 
public Class<?> getColumnClass(int columnIndex) { 
    return ((columnIndex == 0 || columnIndex == 1) ? Boolean.class : String.class); 
} 

@Override 
public boolean isCellEditable(int rowIndex, int columnIndex) { 
    return ((columnIndex == 0 || columnIndex == 1) ? true : false); 
} 

/** 
    **Important:** Here when ever user clicks on the column one then other column values should be made false. Similarly vice-versa is also true. 
**/ 
@Override 
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
    SourceModel model = (SourceModel) sourceList.get(rowIndex); 
    switch (columnIndex) { 
case 0: 
     model.setSelect(true); 
     model.setInActive(false); 
     fireTableRowsUpdated(0, getRowCount() - 1); 
     break; 
case 1: 
     model.setSelect(false); 
     model.setInActive(true); 
     fireTableRowsUpdated(0, getRowCount() - 1); 
     break; 
case 2: 
    model.setFactory((String) aValue); 
    break; 
case 3: 
    model.setSupplier((String) aValue); 
    break; 
} 
fireTableCellUpdated(rowIndex, columnIndex); 
} 

@Override 
public Object getValueAt(int rowIndex, int columnIndex) { 
SourceModel source = sourceList.get(rowIndex); 
//SourceModel source = getSourceDOList().get(rowIndex); 
switch(columnIndex){ 
case 0: 
    return source.isSelect(); 
case 1: 
    return source.isInActive();  
case 2: 
    return source.getFactory(); 
case 3: 
    return source.getSupplier(); 
default: 
    return null; 
} 
} 

/** 
* List for populating the table. 
* @return list of sourceDO's. 
*/ 
private List<SourceModel> getSourceDOList() { 
    List<SourceModel> tempSourceList = new ArrayList<SourceModel>(); 
    for (int index = 0; index < 5; index++) { 

    SourceModel source = new SourceModel(); 
    source.setSelect(false); 
    source.setInActive(false); 
    source.setFactory("One " + index); 
    source.setSupplier("Two " + index); 

    tempSourceList.add(source); 
} 
return tempSourceList; 
} 
} 

/** Class that is holding the model for each row **/ 
class SourceModel { 

private boolean active; 
private boolean inActive; 
private String factory; 
private String supplier; 

public SourceModel() { 
    // No Code; 
} 

public SourceModel(boolean select, boolean inActive, String factory, String supplier) { 
    super(); 
    this.active = select; 
    this.inActive = inActive; 
    this.factory = factory; 
    this.supplier = supplier; 
} 

public boolean isSelect() { 
    return active; 
} 

public void setSelect(boolean select) { 
    this.active = select; 
} 

public String getFactory() { 
    return factory; 
} 

public boolean isInActive() { 
    return inActive; 
} 

public void setInActive(boolean inActive) { 
    this.inActive = inActive; 
} 

public void setFactory(String factory) { 
    this.factory = factory; 
} 

public String getSupplier() { 
    return supplier; 
} 

public void setSupplier(String supplier) { 
    this.supplier = supplier; 
} 
} 

/** Renderer class for JRadioButton **/ 
class RadioButtonRenderer implements TableCellRenderer { 

    public JRadioButton btn = new JRadioButton(); 
    public Component getTableCellRendererComponent(JTable table, Object value, 
     boolean isSelected, boolean hasFocus, int row, int column) { 

     if (value == null) 
      return null; 
     btn.setSelected((Boolean) value); 
     return btn; 
    } 
} 

/** Editor class for JRadioButton **/ 
class RadioButtonEditor extends DefaultCellEditor implements ItemListener { 

public JRadioButton btn = new JRadioButton(); 

public RadioButtonEditor(JCheckBox checkBox) { 
    super(checkBox); 
} 

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

    if (value == null) 
     return null; 

    btn.addItemListener(this); 

    if (((Boolean) value).booleanValue()) 
     btn.setSelected(true); 
    else 
     btn.setSelected(false); 

    return btn; 
} 

public Object getCellEditorValue() { 
    if(btn.isSelected() == true) 
     return new Boolean(true); 
    else 
     return new Boolean(false); 
} 

public void itemStateChanged(ItemEvent e) { 
    super.fireEditingStopped(); 
} 
} 

編輯: 在你需要使用Rendering and Editing使用下面的語句列0和1臺模型定義列後。

sourceTable.getColumnModel().getColumn(1).setCellRenderer(new RadioButtonRenderer()); 
sourceTable.getColumnModel().getColumn(1).setCellEditor(new RadioButtonEditor(new JCheckBox())); 

同樣,你也需要爲第二和第三列(如你所需)做。您需要查看的一個重要步驟是在TableModel中使用setValueAt(..)方法,您需要對列(0,1)和(2,3)進行分組,因此當第0列爲selected時,則將第1列設爲deselected,對於第2列和第3列列。查看案例2下面的setValueAt(..)方法代碼。當用戶選擇第二列時,我們將使該列成爲true,並將第三列作爲false。你只需要爲第2列和第3列做同樣的事情。

case 2: 
     model.setSelect(true); 
     model.setInActive(false); 
     break; 
+1

+1 [sscce](http://sscce.org/),現引用[here](http://stackoverflow.com/a/11173600/230513)。建議:1)使用'@ Override'註釋。 2)在可用時使用靜態工廠,例如'getCellEditorValue()'可以'返回Boolean.valueOf(btn.isSelected())'。 3)在構造函數中調用'addItemListener()',並簡化邏輯,例如'(btn.setSelected((布爾)值).booleanValue())'4)在'setValueAt()'中省略冗餘等級。此代碼爲 – trashgod

+0

thanx先生;如果你能幫我一個忙,那麼兩個單選按鈕在jjtable – user1760166

+0

@trashgod的第3列和第4列謝謝。當然,我會採納你的建議,並嘗試從現在開始練習。 – Amarnath