3

次のコードに問題があります。私の仕事は、最初の列にラジオボタンを配置する必要があり、ユーザーがそのラジオボタンを選択すると、その行が選択されて処理のために送信されることです。しかし、私の問題は、最初の列にあるラジオボタンを選択できることbut afterwards when user clicks in any part of the table then my clicked radio button is being unchecked.です。なぜそれが起こっているのかわかりません。私は本当にこの問題で立ち往生しています。ヘルプが必要です。次のコードは私の問題を示しています。

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

import javax.swing.ButtonGroup;
import javax.swing.DefaultCellEditor;
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;

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

    JPanel panel = new JPanel();
    panel.add(new JScrollPane(sourceTable));
    add(panel);

    setModal(true);
    pack();
    setVisible(true);
}

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


class SourceTableModel extends AbstractTableModel{

private static final long serialVersionUID = 1L;

private List<SourceModel> sourceList = new ArrayList<SourceModel>(); 
private String[] columnNamesList = {"Select", "Group", "Work"};

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

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

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

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

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

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

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    SourceModel model = (SourceModel) sourceList.get(rowIndex);
    switch (columnIndex) {
    case 0: 
        model.setSelect((Boolean)aValue);
        break;
    case 1: 
        model.setFactory((String) aValue);
        break;
    case 2: 
        model.setSupplier((String) aValue);
        break;
    }
    fireTableCellUpdated(rowIndex, columnIndex);
}


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

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.setFactory("group");
        source.setSupplier("Work");

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


class SourceModel {

private boolean select;
private String factory;
private String supplier;

public SourceModel() {
    // No Code;
}

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

public boolean isSelect() {
    return select;
}

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

public String getFactory() {
    return factory;
}

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

public String getSupplier() {
    return supplier;
}

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

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

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;

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

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

  }
}

編集: コードを更新し、最初の列に Boolean クラスを使用しました。The problem which I am facing is, if I remove super.fireEditingStopped(); from RadioButtonEditor class then I am able to check and then if I click at any part of the table then checked one I being unchecked.super.fireEditingStopped(); を維持すると その後、ラジオボタンをチェックすることさえできません。

私はそれを知っています super.fireEditingStopped(); 編集を停止します。しかし、私の質問はそれを確認する方法ですか?

PS:申し訳ありませんが、コード全体を投稿しました。誰かが問題を見るのは簡単だと思いました。

これはプログラムのスクリーンショットです。 ここに画像の説明を入力

4

3 に答える 3

3

あなたの図から、JTable各行には単一のJRadioButton. は不適切であるためButtonGroup、このでは @Guillaume Polet がカスタム マネージャーを使用しています。

于 2012-10-17T11:25:02.990 に答える
2

次のコードに問題があります。私の仕事は、最初の列にラジオボタンを配置する必要があり、ユーザーがそのラジオボタンを選択すると、その行が選択されて処理のために送信されます。しかし、私の問題は、最初の列にあるラジオボタンを選択できることですが、その後、ユーザーがテーブルのいずれかの部分をクリックすると、クリックしたラジオボタンのチェックが外されます。なぜそれが起こっているのか理解できません。私は本当にこの問題で立ち往生しています。ヘルプが必要です。次のコードは私の問題を示しています。

  1. を使用しないでくださいJRadioButton。ブール値のbuilt_inサポートを使用してくださいJTable == JCheckBox

  2. その後、あなたはできるsortingし、filteringに基づいてBoolean value

  3. Stringそれ以外の場合は、 ("true"/ "false")にオーバーライドする必要があります


  4. asの使用法を含むいくつかの良いJRadioButtonsasRendererEditorinがありますJTableJComboBoxEditorRadioButtonGroup

于 2012-10-17T10:30:30.920 に答える
1

ルックアンドフィールを動的に変更する必要がある場合は、CellEditorでコンポーネントを拡張することをお勧めします。

//@see javax/swing/SwingUtilities.java
static void updateRendererOrEditorUI(Object rendererOrEditor) {
    if (rendererOrEditor == null) {
        return;
    }
    Component component = null;
    if (rendererOrEditor instanceof Component) {
        component = (Component)rendererOrEditor;
    }
    if (rendererOrEditor instanceof DefaultCellEditor) {
        //Ahh, AbstractCellEditor ...
        component = ((DefaultCellEditor)rendererOrEditor).getComponent();
    }
    if (component != null) {
        SwingUtilities.updateComponentTreeUI(component);
    }
}

「CellEditorextendsJRadioButton...」の例を次に示します。

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

public class DisplayTable2 extends JDialog {
  public void initialize() {
    Object[][] data = {
      { true,  "Group1", "Work1" }, { false, "Group2", "Work2" },
      { false, "Group3", "Work3" }, { false, "Group4", "Work4" }
    };
    JTable sourceTable = new JTable(new SourceTableModel(data));
    sourceTable.getColumnModel().getColumn(0).setCellRenderer(new RadioButtonRenderer());
    sourceTable.getColumnModel().getColumn(0).setCellEditor(new RadioButtonEditor());

    JPanel panel = new JPanel();
    panel.add(new JScrollPane(sourceTable));
    add(panel);

    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    setModal(true);
    pack();
    setVisible(true);
  }
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override public void run() {
        new DisplayTable2().initialize();
      }
    });
  }
}

class SourceTableModel extends DefaultTableModel {
  private static final String[] columnNamesList = {"Select", "Group", "Work"};
  public SourceTableModel(Object[][] data) {
    super(data, columnNamesList);
  }
  @Override public Class<?> getColumnClass(int columnIndex) {
    return (columnIndex == 0 ? Boolean.class : String.class);
  }
  @Override public boolean isCellEditable(int rowIndex, int columnIndex) {
    return (columnIndex == 0 ? true : false);
  }
  @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    if(columnIndex==0 && aValue instanceof Boolean) {
      //lazy development
      for(int i=0; i<getRowCount(); i++) {
        super.setValueAt(i==rowIndex, i, columnIndex);
      }
    } else {
      super.setValueAt(aValue, rowIndex, columnIndex);
    }
  }
}

class RadioButtonRenderer extends JRadioButton implements TableCellRenderer {
  @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if(value instanceof Boolean) {
      setSelected((Boolean)value);
    }
    return this;
  }
}

class RadioButtonEditor extends JRadioButton implements TableCellEditor {
  public RadioButtonEditor() {
    super();
    addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        fireEditingStopped();
      }
    });
  }
  @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    if(value instanceof Boolean) {
      setSelected((Boolean)value);
    }
    return this;
  }
  @Override public Object getCellEditorValue() {
    return isSelected();
  }

  //Copid from AbstractCellEditor
  //protected EventListenerList listenerList = new EventListenerList();
  //transient protected ChangeEvent changeEvent = null;
  @Override public boolean isCellEditable(EventObject e) {
    return true;
  }
  @Override public boolean shouldSelectCell(EventObject anEvent) {
    return true;
  }
  @Override public boolean stopCellEditing() {
    fireEditingStopped();
    return true;
  }
  @Override public void  cancelCellEditing() {
    fireEditingCanceled();
  }
  @Override public void addCellEditorListener(CellEditorListener l) {
    listenerList.add(CellEditorListener.class, l);
  }
  @Override public void removeCellEditorListener(CellEditorListener l) {
    listenerList.remove(CellEditorListener.class, l);
  }
  public CellEditorListener[] getCellEditorListeners() {
    return listenerList.getListeners(CellEditorListener.class);
  }
  protected void fireEditingStopped() {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for(int i = listeners.length-2; i>=0; i-=2) {
      if(listeners[i]==CellEditorListener.class) {
        // Lazily create the event:
        if(changeEvent == null) changeEvent = new ChangeEvent(this);
        ((CellEditorListener)listeners[i+1]).editingStopped(changeEvent);
      }
    }
  }
  protected void fireEditingCanceled() {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for(int i = listeners.length-2; i>=0; i-=2) {
      if(listeners[i]==CellEditorListener.class) {
        // Lazily create the event:
        if(changeEvent == null) changeEvent = new ChangeEvent(this);
        ((CellEditorListener)listeners[i+1]).editingCanceled(changeEvent);
      }
    }
  }
}
于 2012-10-17T12:23:06.567 に答える