1

jTable最初の列はブール値(チェックボックス用)として設定され、2番目の列は文字列値を持ちます。使用しているNetbeansため、最初の列のすべての行にチェックボックスが追加されました。2列目に値がある行にのみ追加しようとしました。私はそれを試すためのコードを使用しました、

private class CustomCellRenderer extends DefaultTableCellRenderer {

  /* (non-Javadoc)
   * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
   */

        @Override
  public Component  getTableCellRendererComponent(JTable table, Object value,boolean        isSelected, boolean hasFocus, int row, int column) {

    Component rendererComp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus,row, column);

             for(int i=row;i<jTable1.getRowCount();i++){

                if(jTable1.getValueAt(i, 1)==null){
                   jTable1.setValueAt(true, i, 0);
                    //checkbox.setOpaque(false);


                }
            }

        return this ;
  }

 }

上記のforループの他のすべてのチェックボックスに値「true」を設定しようとすると、うまく機能します。残りの行を非表示にするにはどうすればよいですか。

編集:

これに自分のコードを追加しています

   package e2;

    import java.awt.Component;
    import javax.swing.JCheckBox;
    import javax.swing.JTable;
    import javax.swing.table.TableCellRenderer;
    public class JTable_CheckBox extends javax.swing.JFrame {

        /** Creates new form JTable_CheckBox */

        JCheckBox checkbox=new JCheckBox();

        public JTable_CheckBox() {
            initComponents();
               jTable1.setValueAt("John",0,1);
               jTable1.setValueAt("James",1,1);
               jTable1.setValueAt("Janet",2,1);
               jTable1.setValueAt("Tom",3,1);

    jTable1.getColumnModel().getColumn(0).setCellRenderer(new CheckboxCellRenderer());
        }


     public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new JTable_CheckBox().setVisible(true);
                }
            });
        }

        public class CheckboxCellRenderer extends JCheckBox implements TableCellRenderer {

        public CheckboxCellRenderer() {
            setOpaque(false);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                //here i am trying to set check box invisible,but here i am setting as selected

           for(int i=row;i<table.getRowCount();i++){

                    if(table.getValueAt(i, 1)==null){
                       table.setValueAt(true, i, 0);
                        //checkbox.setOpaque(false);

                    }
                }
            return this;
            }

        }
     // Variables declaration - do not modify
        private javax.swing.JScrollPane jScrollPane1;
        private javax.swing.JTable jTable1;
        // End of variables declaration

    }
4

4 に答える 4

4

まず、レンダラー/エディターのメカニズムを理解する必要があります。これを行うには、 Swing タグの説明で参照されているオンライン チュートリアルの対応する章をお読みください。

次に、最適な外観を得るために、JTable 自体によってインストールされたデフォルトを再利用して、次のようなカスタム レンダラーを実装します。

public class CompoundRenderer implements TableCellRenderer {

    TableCellRenderer booleanRenderer;
    TableCellRenderer defaultRenderer;

    public CompoundRenderer(TableCellRenderer booleanRenderer, 
        TableCellRenderer defaultRenderer) {
        this.booleanRenderer = booleanRenderer;
        this.defaultRenderer = defaultRenderer;
    }
    @Override
    public Component getTableCellRendererComponent(..., Object value, ....) {
        if (value instanceof Boolean) {
            return booleanRenderer.getTableCellRendererComponent(...);
        }
        return defaultRenderer.getTableCellRendererComponent(...);
    }
}

// usage
JTable myTable ...
TableCellRenderer compound = new CompoundRenderer(
       myTable.getDefaultRenderer(Boolean.class), myTable.getDefaultRenderer(Object.class));
// either register for all booleans
myTable.setDefaultRenderer(Boolean.class, compound);
// or register for a particular column
myTable.getColumnModel().getColumn(someIndex).setCellRenderer(compound); 
于 2012-07-04T14:24:32.483 に答える
2

TableCellRenderer はテーブルで使用され、同じコンポーネントを再利用してテーブルのさまざまなセルを描画します。テーブルは適切なコンテキスト、コンポーネントの境界を自動的に設定し、描画getTableCellRendererComponentする必要があるテーブルのセルごとに を呼び出します (テーブルが最初に表示されたときにすべての可視セルが描画され、その後、TableModel 通知時に適切なセルが表示されます)。再塗装)。

したがって、TableCellRenderer では、値を設定しようとしてテーブルのセルを反復処理する必要はありません。これは意味がありません。TableCellRender尊重する必要がある契約を持つインターフェイスを実装していることを忘れないでください。

Javadoc から:

セルの描画に使用されるコンポーネントを返します。このメソッドは、描画前にレンダラーを適切に構成するために使用されます。

valueしたがって、パラメータを適切に表すコンポーネントを返すだけで済みます。おそらく、コンポーネントを変更して、セルにフォーカスがあるかどうか、および現在選択されているかどうかを示すことができます。それ以上でもそれ以下でもありません。

さて、あなたの質問に来ます: 値を持つ行にのみチェックボックスを表示したい場合は、チェックボックスを返す TableCellRenderer を実装し、列 1 (2 番目の列) の値に従ってその可視性を変更します。

この例は機能しています:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;

public class TestTable {

    public class CheckboxCellRenderer extends JPanel implements TableCellRenderer {

        private JCheckBox checkBox;

        public CheckboxCellRenderer() {
            super(new FlowLayout(FlowLayout.CENTER, 0, 0));
            setOpaque(false);
            checkBox = new JCheckBox();
            checkBox.setOpaque(false);
            checkBox.setHorizontalAlignment(JCheckBox.CENTER);
            add(checkBox);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Object valueInColumn1 = table.getValueAt(row, 1);
            checkBox.setVisible(valueInColumn1 != null);
            checkBox.setSelected(value instanceof Boolean && (Boolean) value);
            return this;
        }
    }

    private JFrame f;
    private JTable table;

    private class MyObject {
        private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

        private String value;

        private boolean selected;

        public MyObject(String value) {
            this.value = value;
        }

        public PropertyChangeSupport getPropertyChangeSupport() {
            return propertyChangeSupport;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
            propertyChangeSupport.firePropertyChange("value", null, value);
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean selected) {
            if (this.selected != selected) {
                this.selected = selected;
                propertyChangeSupport.firePropertyChange("selected", !selected, selected);
            }
        }

    }

    protected void initUI() {
        List<MyObject> objects = new ArrayList<TestTable.MyObject>();
        for (int i = 0; i < 200; i++) {
            MyObject object = new MyObject(i % 3 == 1 ? null : "Row " + (i + 1));
            objects.add(object);
        }
        table = new JTable(new MyTableModel(objects));
        table.setRowHeight(20);
        table.getColumnModel().getColumn(0).setCellRenderer(new CheckboxCellRenderer());
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JScrollPane(table), BorderLayout.CENTER);
        f.pack();
        f.setVisible(true);

    }

    public class MyTableModel extends AbstractTableModel implements PropertyChangeListener {

        private List<MyObject> objects;

        public MyTableModel(List<MyObject> objects) {
            super();
            this.objects = objects;
            for (MyObject object : objects) {
                object.getPropertyChangeSupport().addPropertyChangeListener(this);
            }
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getSource() instanceof MyObject) {
                int index = objects.indexOf(evt.getSource());
                fireTableRowsUpdated(index, index);
            }
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

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

        public MyObject getValueAt(int row) {
            return objects.get(row);
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            switch (columnIndex) {
            case 0:
                return getValueAt(rowIndex).isSelected();
            case 1:
                return getValueAt(rowIndex).getValue();
            }
            return null;
        }

        @Override
        public void setValueAt(Object value, int rowIndex, int columnIndex) {
            if (columnIndex == 0) {
                getValueAt(rowIndex).setSelected(Boolean.TRUE.equals(value));
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 0 && getValueAt(rowIndex).getValue() != null;
        }

        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
            case 0:
                return Boolean.class;
            case 1:
                return String.class;
            }
            return Object.class;
        }

        @Override
        public String getColumnName(int column) {
            switch (column) {
            case 0:
                return "Selected";
            case 1:
                return "Value";
            }
            return null;
        }

    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTable().initUI();
            }
        });
    }

}

PS: isSelected/hasFocus は考慮していません。

于 2012-07-04T12:21:23.987 に答える