org.wings.plaf.css.TreeCG Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2000,2005 wingS development team.
*
* This file is part of wingS (http://wingsframework.org).
*
* wingS is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* Please see COPYING for the complete licence.
*/
package org.wings.plaf.css;
import org.wings.*;
import org.wings.io.Device;
import org.wings.plaf.CGManager;
import org.wings.plaf.Update;
import org.wings.resource.ResourceManager;
import org.wings.tree.SDefaultTreeSelectionModel;
import org.wings.tree.STreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.List;
public final class TreeCG extends AbstractComponentCG implements org.wings.plaf.TreeCG {
private static final long serialVersionUID = 1L;
private SIcon collapseControlIcon;
private SIcon emptyFillIcon;
private SIcon expandControlIcon;
private SIcon hashMark;
private SIcon leafControlIcon;
private SResourceIcon lineslash;
private SResourceIcon lineplus;
private SResourceIcon lineminus;
private boolean renderSelectableCells = true;
/**
* Initialize properties from config
*/
public TreeCG() {
this.collapseControlIcon = (SIcon) ResourceManager.getObject("TreeCG.collapseControlIcon", SIcon.class);
this.emptyFillIcon = (SIcon) ResourceManager.getObject("TreeCG.emptyFillIcon", SIcon.class);
this.expandControlIcon = (SIcon) ResourceManager.getObject("TreeCG.expandControlIcon", SIcon.class);
this.hashMark = (SIcon) ResourceManager.getObject("TreeCG.hashMark", SIcon.class);
this.leafControlIcon = (SIcon) ResourceManager.getObject("TreeCG.leafControlIcon", SIcon.class);
lineslash = new SResourceIcon("org/wings/icons/lineslash.gif");
lineslash.getId();
lineplus = new SResourceIcon("org/wings/icons/lineplus.gif");
lineplus.getId();
lineminus = new SResourceIcon("org/wings/icons/lineminus.gif");
lineminus.getId();
}
@Override
public void installCG(final SComponent comp) {
super.installCG(comp);
final STree component = (STree) comp;
final CGManager manager = component.getSession().getCGManager();
Object value = manager.getObject("STree.cellRenderer", STreeCellRenderer.class);
if (value != null) {
component.setCellRenderer((STreeCellRenderer) value);
}
value = manager.getObject("STree.nodeIndentDepth", Integer.class);
if (value != null) {
component.setNodeIndentDepth((Integer) value);
}
}
public boolean isRenderSelectableCells() {
return renderSelectableCells;
}
public void setRenderSelectableCells(boolean renderSelectableCells) {
this.renderSelectableCells = renderSelectableCells;
}
private static void writeIcon(Device device, SIcon icon) throws IOException {
if (icon == null) {
return;
}
device.print("");
}
private void writeTreeNode(STree component, Device device, int row, int depth)
throws IOException {
final TreePath path = component.getPathForRow(row);
final Object node = path.getLastPathComponent();
final STreeCellRenderer cellRenderer = component.getCellRenderer();
TreeModel model = component.getModel();
final boolean isLeaf = model.isLeaf(node);
final boolean isExpanded = component.isExpanded(path);
final boolean isSelected = component.isPathSelected(path);
final boolean isSelectable = renderSelectableCells && (component.getSelectionModel() != SDefaultTreeSelectionModel.NO_SELECTION_MODEL);
SComponent cellComp = cellRenderer.getTreeCellRendererComponent(component, node,
isSelected,
isExpanded,
isLeaf, row,
false);
device.print("");
String[] images = new String[] {
" class=\"slash\"",
" class=\"plus\"",
"",
" class=\"minus\"",
};
Object[] pathElements = path.getPath();
Object parentElement = component.isRootVisible() ? null : model.getRoot();
for (int i = component.isRootVisible() ? 0 : 1; i < pathElements.length; i++) {
Object element = pathElements[i];
boolean lastElement = i == pathElements.length - 1;
boolean lastChild = lastChild(model, parentElement, element);
int imageIndex = (lastElement ? 1 : 0) + (lastChild ? 2 : 0);
device.print("");
if (lastElement && !(isLeaf && leafControlIcon == null))
renderControlIcon(device, isLeaf, isExpanded);
device.print(" ");
parentElement = element;
}
/*
* now, write the component.
*/
device.print("");
SCellRendererPane rendererPane = component.getCellRendererPane();
rendererPane.writeComponent(device, cellComp, component);
device.print(" ");
Utils.printNewline(device, component);
}
private void renderControlIcon(Device device, boolean leaf, boolean expanded) throws IOException {
if (leaf) {
writeIcon(device, leafControlIcon);
}
else if (expanded) {
if (collapseControlIcon == null) {
device.print("-");
}
else {
writeIcon(device, collapseControlIcon);
}
}
else {
if (expandControlIcon == null) {
device.print("+");
}
else {
writeIcon(device, expandControlIcon);
}
}
}
private static boolean lastChild(TreeModel model, Object parentElement, Object element) {
return parentElement == null || model.getIndexOfChild(parentElement, element) == model.getChildCount(parentElement) - 1;
}
@Override
public void writeInternal(final Device device, final SComponent _c) throws IOException {
final STree tree = (STree) _c;
Rectangle currentViewport = tree.getViewportSize();
Rectangle maximalViewport = tree.getScrollableViewportSize();
int start = 0;
int end = tree.getRowCount();
int empty = maximalViewport != null ? maximalViewport.height : end;
if (currentViewport != null) {
start = currentViewport.y;
end = start + currentViewport.height;
}
final int depth = tree.getMaximumExpandedDepth();
device.print("");
for (int i = start; i < end; ++i) {
if (i >= empty) {
device.print(" ");
continue;
}
writeTreeNode(tree, device, i, depth);
}
device.print("
");
}
//--- setters and getters for the properties.
public SIcon getCollapseControlIcon() {
return collapseControlIcon;
}
public void setCollapseControlIcon(SIcon collapseControlIcon) {
this.collapseControlIcon = collapseControlIcon;
}
public SIcon getEmptyFillIcon() {
return emptyFillIcon;
}
public void setEmptyFillIcon(SIcon emptyFillIcon) {
this.emptyFillIcon = emptyFillIcon;
}
public SIcon getExpandControlIcon() {
return expandControlIcon;
}
public void setExpandControlIcon(SIcon expandControlIcon) {
this.expandControlIcon = expandControlIcon;
}
public SIcon getHashMark() {
return hashMark;
}
public void setHashMark(SIcon hashMark) {
this.hashMark = hashMark;
}
public SIcon getLeafControlIcon() {
return leafControlIcon;
}
public void setLeafControlIcon(SIcon leafControlIcon) {
this.leafControlIcon = leafControlIcon;
}
@Override
public Update getSelectionUpdate(STree tree, List deselectedRows, List selectedRows) {
return new SelectionUpdate(tree, deselectedRows, selectedRows);
}
protected static class SelectionUpdate extends AbstractUpdate {
private List deselectedRows;
private List selectedRows;
public SelectionUpdate(SComponent component, List deselectedRows, List selectedRows) {
super(component);
this.deselectedRows = deselectedRows;
this.selectedRows = selectedRows;
}
@Override
public Handler getHandler() {
UpdateHandler handler = new UpdateHandler("selectionTree");
handler.addParameter(component.getName());
handler.addParameter(Utils.listToJsArray(deselectedRows));
handler.addParameter(Utils.listToJsArray(selectedRows));
return handler;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
SelectionUpdate that = (SelectionUpdate) o;
if (deselectedRows != null ? !deselectedRows.equals(that.deselectedRows) : that.deselectedRows != null)
return false;
return selectedRows != null ? selectedRows.equals(that.selectedRows) : that.selectedRows == null;
}
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (deselectedRows != null ? deselectedRows.hashCode() : 0);
result = 31 * result + (selectedRows != null ? selectedRows.hashCode() : 0);
return result;
}
}
}