2

我想要一个JTable由 2 列(具有RadioButton) Active 和 Inactive 组成的,这样如果 Active Column 是Selected那么 Inactive RadioButton 就会得到Unselected,反之亦然意味着在单行中只能从 2 个单选按钮中选择 1 个单选按钮。单选按钮的代码如下。我无法为这 2 列添加 2 个按钮组。

 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);
                }
            });
        }
4

1 回答 1

8

这是我拥有的示例代码,我对其进行了修改并将另一个JRadioButton放在第 2 列中以满足您的要求。第一列和第二列都像 ButtonGroup 一样按行分组。

输出:

在此处输入图像描述

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()));

同样,您也需要对第二列和第三列(根据需要)进行操作。您必须查看的一个重要步骤是setValueAt(..)TableModel 中的方法,您需要对列 (0, 1) 和 (2, 3) 进行分组,因此当第 0 列selected成为第 1 列时,第deselected2 列和第 3 列也是如此。查看setValueAt(..)下面案例 2 的方法代码。当用户选择第二列时,我们将该列设为真,第三列设为假。您只需要对第 2 列和第 3 列执行相同的操作。

   case 2:
        model.setSelect(true);
        model.setInActive(false);
        break;
于 2012-12-24T13:52:39.060 回答