/* * Beanfabrics Framework Copyright (C) by Michael Karneim, beanfabrics.org * Use is subject to license terms. See license.txt. */ // TODO javadoc - remove this comment only when the class and all non-public // methods and fields are documented package org.beanfabrics.swing.table.cellrenderer; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import javax.swing.CellRendererPane; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import org.beanfabrics.model.ConversionException; import org.beanfabrics.model.IBooleanPM; import org.beanfabrics.swing.ErrorIconPainter; /** * {@link TableCellRenderer} that renders the value of a {@link IBooleanPM}. * * @author Michael Karneim */ // TODO (mk) this class contains several workarounds for a bug // in nimbus l&f: the alternating background is painted wrong if we // don't extend the DefaultTableCellRenderer. See mantis 0000029. @SuppressWarnings("serial") public class BooleanPMTableCellRenderer extends JPanel implements TableCellRenderer { private CellRendererPane cellRendererPane = new CellRendererPane(); private JCheckBox cb = new JCheckBox(); private DefaultTableCellRenderer defaultRenderer = new DefaultTableCellRenderer(); private ErrorIconPainter errorIconPainter = createDefaultErrorIconPainter(); private IBooleanPM model; private JComponent rendererComponent; public BooleanPMTableCellRenderer() { super(); cb.setHorizontalAlignment(SwingConstants.CENTER); cb.setBorderPainted(false); cb.setOpaque(false); this.setLayout(new BorderLayout()); this.add(this.cb, BorderLayout.CENTER); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof IBooleanPM == false) { return null; } model = (IBooleanPM)value; Boolean bvalue = false; try { Boolean modelBoolean = model.getBoolean(); if (modelBoolean != null) { bvalue = modelBoolean; } } catch (ConversionException e) { // can't convert model value to Boolean object // -> handle it as 'false' } cb.setSelected(bvalue); cb.setEnabled(table.getModel().isCellEditable(row, column)); if (isNimbus()) { // one more work around if (rendererComponent != null) { rendererComponent.setBackground(null); } rendererComponent = (JComponent)defaultRenderer.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column); if (isSelected == false && row % 2 != 0) { rendererComponent.setBackground(Color.white); } } else { rendererComponent = (JComponent)defaultRenderer.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column); } return this; } private boolean isNimbus() { return "Nimbus".equals(UIManager.getLookAndFeel().getID()); } @Override public void setBackground(Color bg) { super.setBackground(bg); if (rendererComponent != null) { rendererComponent.setBackground(bg); } } @Override public void setForeground(Color fg) { super.setForeground(fg); if (rendererComponent != null) { rendererComponent.setForeground(fg); } } /** * This method is called right before {@link #paintChildren(Graphics)} * (where we paint the checkbox). So we can override the background * painting. */ @Override public void paintComponent(Graphics g) { super.paintComponent(g); cellRendererPane.paintComponent(g, rendererComponent, this, 0, 0, getWidth(), getHeight()); } /** {@inheritDoc} */ @Override public void paint(Graphics g) { super.paint(g); // TODO shouldn't this be moved to the method paintComponent() //this.paintErrorIcon(g); } private ErrorIconPainter createDefaultErrorIconPainter() { ErrorIconPainter result = new ErrorIconPainter(); return result; } public ErrorIconPainter getErrorIconPainter() { return errorIconPainter; } public void setErrorIconPainter(ErrorIconPainter aErrorIconPainter) { if (aErrorIconPainter == null) { throw new IllegalArgumentException("aErrorIconPainter == null"); } this.errorIconPainter = aErrorIconPainter; } /** {@inheritDoc} */ @Override public void paintChildren(Graphics g) { super.paintChildren(g); if (shouldPaintErrorIcon()) { errorIconPainter.paint(g, this); } } private boolean shouldPaintErrorIcon() { if (model == null) { return false; } return (model.isValid() == false); } }