Как сделать флажок в JTable? - PullRequest
5 голосов
/ 11 ноября 2010

Это мой код для рендеринга JTable и изменения цвета строк, но в столбце 6 не отображается флажок, только строка (true, false).

Можете ли вы предоставить решение дляисправить это?

Заранее спасибо.

    public class JLabelRenderer extends JLabel implements TableCellRenderer
{
  private MyJTable myTable;
  /**
   * Creates a Custom JLabel Cell Renderer
   * @param t your JTable implmentation that holds the Hashtable to inquire for
   * rows and colors to paint.
   */
  public JLabelRenderer(MyJTable t)
  {
    this.myTable = t;
  }

  /**
   * Returns the component used for drawing the cell.  This method is
   * used to configure the renderer appropriately before drawing.
   * see TableCellRenderer.getTableCellRendererComponent(...); for more comments on the method
   */
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
  {
    setOpaque(true); //JLabel isn't opaque by default

    setText(value.toString());
    setFont(myTable.getFont());

    if(!isSelected)//if the row is not selected then use the custom color
    setBackground(myTable.getRowToPaint(row));
    else //if the row is selected use the default selection color
    setBackground(myTable.getSelectionBackground());

    //Foreground could be changed using another Hashtable...
    setForeground(myTable.getForeground());

    // Since the renderer is a component, return itself
    return this;
  }

  // The following methods override the defaults for performance reasons
  public void validate() {}
  public void revalidate() {}
  protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
  public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
}

Это таблица:

import javax.swing.JTable;    
import javax.swing.table.*;
import java.util.Hashtable;
import java.awt.Color;

public class MyJTable extends JTable
{
  Hashtable rowsToPaint = new Hashtable(1);

  /**
   * Default Constructor
   */
  public MyJTable()
  {
    super();
  }

  /**
   * Set the TableModel and then render each column with a custom cell renderer
   * @param tm TableModel
   */
  public void setModel(TableModel tm)
  {
    super.setModel(tm);
    renderColumns(new JLabelRenderer(this));
  }

  /**
   * Add a new entry indicating:
   * @param row the row to paint - the first row = 0;
   * @param bgColor background color
   */
  public void addRowToPaint(int row, Color bgColor)
  {
    rowsToPaint.put(new Integer(row), bgColor);
    this.repaint();// you need to repaint the table for each you put in the hashtable.
  }

  /**
   * Returns the user selected BG Color or default BG Color.
   * @param row the row to paint
   * @return Color BG Color selected by the user for the row
   */
  public Color getRowToPaint(int row)
  {
    Color bgColor = (Color)rowsToPaint.get(new Integer(row));
    return (bgColor != null)?bgColor:getBackground();
  }

  /**
   * Render all columns with the specified cell renderer
   * @param cellRender TableCellRenderer
   */
  public  void renderColumns(TableCellRenderer cellRender)
  {
    for(int i=0; i<this.getModel().getColumnCount(); i++)
    {
      renderColumn(this.getColumnModel().getColumn(i), cellRender);
    }
  }

  /**
   * Render a TableColumn with the sepecified Cell Renderer
   * @param col TableColumn
   * @param cellRender TableCellRenderer
   */
  public void renderColumn(TableColumn col, TableCellRenderer cellRender)
  {
    try{
          col.setCellRenderer(cellRender);
        }catch(Exception e){System.err.println("Error rendering column: [HeaderValue]: "+col.getHeaderValue().toString()+" [Identifier]: "+col.getIdentifier().toString());}
  }
}

вот мой экран alt text

Ответы [ 4 ]

7 голосов
/ 11 ноября 2010

Лучшее решение этой проблемы - реализовать собственный TableModel (обычно с помощью подкласса AbstractTableModel) и реализовать метод getColumnClass(int), возвращающий Boolean.class для столбца, который вы хотите отобразить как JCheckBox.

Нет необходимости реализовывать свой собственный TableCellRenderer, поскольку DefaultTableCellRenderer, используемый JTable по умолчанию, автоматически отображает Boolean столбцы как JCheckbox es.

3 голосов
/ 11 ноября 2010

Спасибо Акф я решил это следующим образом:

добавить класс:

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) {
            if (isSelected) {
              setForeground(table.getSelectionForeground());
              //super.setBackground(table.getSelectionBackground());
              setBackground(table.getSelectionBackground());
            } else {
              setForeground(table.getForeground());
              setBackground(table.getBackground());
            }
            setSelected((value != null && ((Boolean) value).booleanValue()));
            return this;
          }
}

Редактор конструктора Mytable:

 public MyJTable(DefaultTableModel md)
  {
    super(md);
    CheckBoxRenderer checkBoxRenderer = new CheckBoxRenderer();
    this.getColumnModel().getColumn(6).setCellRenderer(checkBoxRenderer);
  }
3 голосов
/ 11 ноября 2010

Как вы, вероятно, знаете, JTable будет отображать логические значения в качестве флажков для вас. Я полагаю, что ваша проблема в том, что вы не можете установить собственный цвет фона для строки на основе определенных критериев в ваших данных. Вы можете создать новый TableCellRenderer для своего столбца boolean.

У вас есть пара вариантов:

  1. вы можете поставить тест в вашем текущем рендерере, чтобы определить, является ли переданный value логическим или нет, и если это так, сконфигурировать экземпляр JCheckbox, который будет возвращен. Это может повлиять на то, что вы хотите, но вам нужно быть осторожным, так как ваш рендерер часто вызывается и если вы создаете одноразовые JCheckbox es, это может вызвать большой отток.

  2. в качестве альтернативы, вы можете создать новый TableCellRenderer, который расширяет JCheckbox (так же, как ваш текущий расширяет JLabel. Вы хотели бы реорганизовать вашу текущую логику окраски так, чтобы она могла быть разделена между двумя И наконец, вы хотите связать этот рендерер со своим столбцом. Это можно сделать, установив его в качестве средства рендеринга по умолчанию для таблицы для определенного Class (myTable.setDefaultRenderer(Class, TableCellRenderer)), или установив его в качестве рендерера для определенный столбец (myTable.getColumnModel().getColumn(int).setCellRenderer(TableCellRenderer))

1 голос
/ 11 ноября 2010

Мне проще использовать Table Row Rendering для чего-то подобного. Он будет работать без создания отдельных средств визуализации для каждого столбца.

...