Archive

Archive for November, 2011

Recipe 7: Decorate an OutlineView

November 28, 2011 1 comment

Problem

When an OutlineView is not editable, its cells appear grey and the property editor button is shown. How do I decorate a read-only OutlineView?

Solution

Use the following custom cell renderer in NetBeans 7.0 and above:

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import org.netbeans.swing.outline.DefaultOutlineCellRenderer;
import org.openide.awt.HtmlRenderer;
import org.openide.nodes.Node.Property;
import org.openide.util.Exceptions;
/**
 * Renderer used to remove the property editor button and the grey appearance of the cells of an outline view.
 * It uses the <@link PropertyTextRenderer/> of the property if any was set.
 */
public class CustomOutlineCellRenderer extends DefaultOutlineCellRenderer {

 /** Gray Color for the odd lines in the view. */
 private static final Color VERY_LIGHT_GRAY = new Color(236, 236, 236);
 /** Center the content of the cells displaying text. */
 protected boolean centered = System.getProperty("os.name").toLowerCase().indexOf("windows") < 0;
 /** Highlight the non editable cells making the foreground lighter.*/
 protected boolean lighterEditableFields = false;
 @Override
 @SuppressWarnings("unchecked")
 public Component getTableCellRendererComponent(final JTable table,
                                                final Object value,
                                                final boolean isSelected,
                                                final boolean hasFocus,
                                                final int row,
                                                final int column) {
  Component cell = null;
  Object valueToDisplay = value;
  if (value instanceof Property) {
     try {
        valueToDisplay = ((Property) value).getValue();
     } catch (IllegalAccessException ex) {
        Exceptions.printStackTrace(ex);
     } catch (InvocationTargetException ex) {
        Exceptions.printStackTrace(ex);
     }
  }
  if (valueToDisplay != null) {
    TableCellRenderer renderer = table.getDefaultRenderer(valueToDisplay.getClass());
    if (renderer != null) {
       cell = renderer.getTableCellRendererComponent(table, valueToDisplay, isSelected,
                                                     hasFocus, row, column);
    }
  } else {
       cell = super.getTableCellRendererComponent(table, valueToDisplay, isSelected, hasFocus, row, column);
  }
  if (cell != null) {
     if (centered) {
        if (cell instanceof HtmlRenderer.Renderer) {
           ((HtmlRenderer.Renderer) cell).setCentered(centered);
        } else if (cell instanceof DefaultTableCellRenderer.UIResource) {
           ((DefaultTableCellRenderer.UIResource) cell).setHorizontalAlignment(JLabel.CENTER);
        }
     }
     Color foregroundColor = table.getForeground();
     int modelRow = table.convertRowIndexToModel(row);
     int modelColumn = table.convertColumnIndexToModel(column);
     final boolean cellEditable = table.getModel().isCellEditable(modelRow, modelColumn);
     if (lighterEditableFields && cellEditable) {
        foregroundColor = Color.BLUE;
     }
     cell.setForeground(foregroundColor);
     cell.setBackground(row % 2 == 0 ? Color.WHITE : VERY_LIGHT_GRAY);
     if (isSelected) {
        if (lighterEditableFields && cellEditable) {
           cell.setFont(cell.getFont().deriveFont(Font.BOLD));
        }
        cell.setBackground(table.getSelectionBackground());
     }
  }
  return cell;
 }
 /**
   * @return true if the text rendered in labels is centered.
   */
 public boolean isCentered() {
    return centered;
 }

 /**
  * Center the content of the cells displaying text.
  *
  * @param value true to center, false for default alignment.
  */
 public void setCentered(final boolean value) {
    this.centered = value;
 }

 /**
  * @return true if non editable cells have a lighter foreground.
  */
 public boolean isLighterEditableFields() {
    return lighterEditableFields;
 }

 /**
  * Highlight the non editable cells making the foreground lighter.
  *
  * @param value true to activate this feature.
  */
 public void setLighterEditableFields(final boolean value) {
    this.lighterEditableFields = value;
 }
}

Then you can use it in your outline view like so:

outlineView.getOutline().setDefaultRenderer(Node.Property.class,
                                            new CustomOutlineCellRenderer());

If you need more customisation:

outlineView.getOutline().setDefaultRenderer(Node.Property.class,
new CustomOutlineCellRenderer() {

 @Override
 public Component getTableCellRendererComponent(final JTable table, final Object value,
                                               final boolean isSelected,
                                               final boolean hasFocus,
                                               final int row, final int column) {
  JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
  int modelRow = table.convertRowIndexToModel(row);
  Node node = EXPLORER_MANAGER.getRootContext().getChildren().getNodeAt(modelRow);
  if (node != null) {
     if (isSelected) {
        cell.setFont(cell.getFont().deriveFont(Font.BOLD));
     } else {
        cell.setFont(cell.getFont().deriveFont(Font.PLAIN));
     }
     cell.setBackground(Color.black);
     cell.setForeground(Color.white);
  }
  return cell;
 }
});

Recipe 6: Sort an OutlineView programmatically

November 27, 2011 Leave a comment

Problem

How can I sort a column of an OutlineView programmatically?

Solution

You can click on the header of a column in an OutlineView to sort it in ascending/descending order. But how can you do this programmatically? E.g. when you click on a button you wish to have the outline view sorted by one column, and when you click another button to have it sorted based on another column:

/**
 * Sort the outline view {@code ov} on the given {@code field}.
 * @param ov outline view to sort
 * @param field to sort upon
 * @param ascending if {@code true} then the list is sorted in ascending order, if {@code false} in descending order.
 */
public static void sortBy(final OutlineView ov, final String field, final boolean ascending) {
  ETableColumnModel columnModel = (ETableColumnModel) ov.getOutline().getColumnModel();
  int columnCount = columnModel.getColumnCount();
  columnModel.clearSortedColumns();
  for (int i = 0; i < columnCount; i++) {
    ETableColumn column = (ETableColumn)columnModel.getColumn(i);
    if (column.getHeaderValue().equals(field)) {
      columnModel.setColumnSorted(column, ascending, 1);
    }
  }
  TableModel model = ov.getOutline().getModel();
  ov.getOutline().tableChanged(new TableModelEvent(model, 0, model.getRowCount()));
}
Categories: OutlineView Tags: ,