2012-07-04 6 views
1

У меня есть jTable с двумя столбцами. Первый столбец задан как булевский (для флажка), а второй столбец имеет значение String. Поскольку я использую Netbeans, флажок был добавлен во все строки первого столбца. Я попытался добавить его только для тех строк, которые имеют значение во втором столбце. Я использовал код пытаюсь чтоНастройка jCheckBox невидима в jTable

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

} 

Если я пытаюсь установить значение «True» для всех другого флажка в выше для цикла он хорошо работает. Как я могу установить его невидимым для остальной части строк.

EDIT:

Я добавляю свой код в этом

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 

    } 
+0

try checkbox.setVisible (false); –

+0

Я тоже это пробовал ... ничего не происходит .. :( – Luna

+1

unrelated: _never-ever_ изменить любое состояние таблицы в рендерере – kleopatra

ответ

2

TableCellRenderer используются в таблицах расписывать различные ячейки таблицы повторного использования и тот же компонент. Таблица автоматически устанавливает правильный контекст, границы компонентов и вызывает getTableCellRendererComponent для каждой ячейки таблицы, которая должна быть окрашена (при первом отображении таблицы все видимые ячейки окрашиваются, а затем после уведомления о таблицеModel соответствующие ячейки перекрашены).

Так что в вашем TableCellRenderer вам, разумеется, не нужно перебирать ячейки таблицы, пытаясь установить значения. Это просто не имеет смысла. Помните, что вы реализуете интерфейс TableCellRender, у которого есть контракт, который вам нужно уважать.

Из Javadoc:

Возвращает компонент, используемый для рисования ячейки. Этот метод используется , чтобы настроить рендеринг соответствующим образом перед рисованием.

Итак, все, что вам нужно сделать, это вернуть компонент, представляющий параметр value. Возможно, вы можете изменить компонент, чтобы указать, что ячейка имеет фокус или нет, и выбирайте ее в данный момент или нет. Ни больше ни меньше.

Теперь, придя к вашему вопросу: если вы хотите отображать флажок только для строк, которые имеют значение, реализуют TableCellRenderer, возвращая флажок и изменяя его видимость в соответствии со значением в столбце 1 (второй столбец).

Этот пример работает:

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 во внимание, если вы хотите, мы можем прийти к этому позже.

+0

Спасибо ... теперь у меня есть идея. Не могли бы вы рассказать мне значение эта строка ... "setSelected (value instanceof Boolean && (Boolean) value);" – Luna

+0

Можем ли мы сделать это (буквально), проверить значение строки column1, если оно равно null принять значение компонента в столбце 0 и сделать setVisible false.Am i right? – Luna

+0

@Tickua Средство рендеринга возвращает флажок, поэтому 'setSelected (value instanceof Boolean && (Boolean) value);' просто сделает флажок выбранным, если 'value' является логическим, и его значение равно на 'true'. –

4

Во-первых, вы должны понимать механизм визуализации/редактора. Для этого прочитайте f.i. соответствующую главу в онлайн-учебнике, указанную в Swing tag description.

Во-вторых, для лучшего внешнего вида, реализовать пользовательский визуализатор путем повторного использования по умолчанию, установленные самим 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); 
1

Как говорится: многие пути ведут в Рим.

У меня была аналогичная проблема: у меня есть таблица с столбцом, содержащим флажки, и я хочу скрыть этот флажок в первой строке. После оценки других решений я придумать что-то немного другое (адаптированное для оригинального вопроса):

Создать специальный класс CheckBoxRenderer:

public class CheckBoxRenderer extends JCheckBox implements TableCellRenderer { 

    CheckBoxRenderer() { 
     setHorizontalAlignment(JLabel.CENTER); 
    } 

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

     Object valueInColumn1 = table.getValueAt(row, 1); 
     if (valueInColumn1 == null) { 
      JLabel x=new JLabel(); 
      return x; 
     } 
     setSelected((value != null && ((Boolean) value).booleanValue())); 
     return this; 
    } 
} 

Шаг № 2: присоедините рендерер того колонка:

paramTable.getColumnModel().getColumn(3).setCellRenderer(new CheckBoxRenderer()); 

Все.

0

Я знаю, что это старая нить, но у меня была аналогичная потребность, и я нашел ответы на них весьма полезными. Одно дополнение, которое я обнаружил, что мне нужно было включить, было создание CheckBoxEditor. В противном случае, когда я нажал на ячейку, я увидел, что флажок появился на мгновение. Поэтому я добавил что-то вроде этого:

public class CheckBoxEditor extends DefaultCellEditor 
{ 
    private JCheckBox checkBox = new JCheckBox(); 

    CheckBoxEditor() 
    { 
     super(checkBox); 
    } 

    @Override 
    public Component getTableCellEditorComponent(
         JTable table, 
         Object value, 
         boolean isSelected, 
         int  row, 
         int  column) 
    { 
     if (row != 1) 
     { 
     return super.getTableCellEditorComponent(
         table, value, isSelected, row, column); 
     } 
     else 
     { 
     return null; 
     } 
    } 
} 

Тогда вы могли бы сделать что-то вроде:

paramTable.getColumnModel().getColumn(3).setCellEditor(new CheckBoxEditor()); 

работал для меня, во всяком случае.

Еще одно замечание, что если ваши клетки имеют цвет фона, вы можете продлить ГКР ответ, добавив следующие строки:

x.setOpaque(true); 
x.setBackground(MYCOLOR); 

Установка JLabel в непрозрачной является ключом, как можно найти в других Stack бирже ответы на похожие темы.

Смежные вопросы