/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.bearsoft.gui.grid.header; import java.awt.Color; import java.awt.Font; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.List; import javax.swing.table.TableColumn; /** * * @author mg */ public class GridColumnsNode implements ColumnNodesContainer { protected Color background; protected Color foreground; protected Font font; protected GridColumnsNode parent; protected int minWidth; protected int maxWidth = Integer.MAX_VALUE / 2; protected boolean movable = true; protected boolean resizable = true; protected boolean sortable = true; protected boolean readonly; protected boolean enabled = true; protected boolean visible = true; protected String title; protected boolean selectOnly; protected List<GridColumnsNode> children = new ArrayList<>(); // events sources protected TableColumn tableColumn; protected GridColumnsNode styleSource; protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); // because of nodes cloning protected PropertyChangeListener styleListener = (PropertyChangeEvent evt) -> { switch (evt.getPropertyName()) { case "font": font = styleSource.getFont(); changeSupport.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); break; case "background": background = styleSource.getBackground(); changeSupport.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); break; case "foreground": foreground = styleSource.getForeground(); changeSupport.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); break; case "title": title = styleSource.getTitle(); changeSupport.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); break; } }; protected PropertyChangeListener childrenListener = (PropertyChangeEvent evt) -> { changeSupport.firePropertyChange(evt.getPropertyName(), null, children); }; public GridColumnsNode() { super(); } public GridColumnsNode(String aTitle) { this(); title = aTitle; } /** * Constructor of grid columns group with parent specified. * * @param aParent Parent group, the new group is to be added to; */ public GridColumnsNode(GridColumnsNode aParent) { this(); setParent(aParent); } /** * Constructor of grid columns group based on table column information. It's * allowed only if this column group is a leaf group. * * @param aCol Table column instance to get information from. * @see TableColumn */ public GridColumnsNode(TableColumn aCol) { this(); setTableColumn(aCol); } public PropertyChangeSupport getChangeSupport() { return changeSupport; } public final void setParent(GridColumnsNode aParent) { parent = aParent; } public GridColumnsNode getStyleSource() { return styleSource; } public void setStyleSource(GridColumnsNode aValue) { if (styleSource != aValue) { if (styleSource != null) { styleSource.getChangeSupport().removePropertyChangeListener(styleListener); } styleSource = aValue; if (styleSource != null) { styleSource.getChangeSupport().addPropertyChangeListener(styleListener); } } } public boolean containsInChildren(GridColumnsNode aChild) { return children != null && children.indexOf(aChild) != -1; } public GridColumnsNode getParent() { return parent; } public TableColumn getTableColumn() { return tableColumn; } protected PropertyChangeListener columnListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("headerValue".equals(evt.getPropertyName()) && (evt.getNewValue() == null || evt.getNewValue() instanceof String)) { title = (String) evt.getNewValue(); } else if ("width".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Integer) { changeSupport.firePropertyChange("width", evt.getOldValue(), evt.getNewValue()); } else if ("preferredWidth".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Integer) { changeSupport.firePropertyChange("preferredWidth", evt.getOldValue(), evt.getNewValue()); } else if ("minWidth".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Integer) { minWidth = (Integer) evt.getNewValue(); changeSupport.firePropertyChange("minWidth", evt.getOldValue(), evt.getNewValue()); } else if ("maxWidth".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Integer) { maxWidth = (Integer) evt.getNewValue(); changeSupport.firePropertyChange("maxWidth", evt.getOldValue(), evt.getNewValue()); } else if ("movable".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Boolean) { movable = (Boolean) evt.getNewValue(); } else if ("resizable".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Boolean) { resizable = (Boolean) evt.getNewValue(); } else if ("sortable".equals(evt.getPropertyName()) && evt.getNewValue() instanceof Boolean) { sortable = (Boolean) evt.getNewValue(); } changeSupport.firePropertyChange("headerValue".equals(evt.getPropertyName()) ? "title" : evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); } }; public final void setTableColumn(TableColumn aColumn) { if (tableColumn != null) { tableColumn.removePropertyChangeListener(columnListener); } if (aColumn == null && tableColumn != null) { minWidth = tableColumn.getMinWidth(); maxWidth = tableColumn.getMaxWidth(); if (tableColumn.getHeaderValue() instanceof String) { title = (String) tableColumn.getHeaderValue(); } } tableColumn = aColumn; if (tableColumn != null) { tableColumn.addPropertyChangeListener(columnListener); } } public void lightAssign(GridColumnsNode aSource) { if (aSource != null) { enabled = aSource.isEnabled(); minWidth = aSource.getMinWidth(); maxWidth = aSource.getMaxWidth(); readonly = aSource.isReadonly(); visible = aSource.isVisible(); selectOnly = aSource.isSelectOnly(); movable = aSource.isMovable(); resizable = aSource.isResizable(); sortable = aSource.isSortable(); title = aSource.getTitle(); background = aSource.getBackground(); foreground = aSource.getForeground(); font = aSource.getFont(); } else { readonly = false; enabled = true; visible = true; title = null; selectOnly = false; movable = true; resizable = true; sortable = true; background = null; foreground = null; font = null; } } public boolean lightEquals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final GridColumnsNode other = (GridColumnsNode) obj; if (this.minWidth != other.minWidth) { return false; } if (this.maxWidth != other.maxWidth) { return false; } if (this.readonly != other.readonly) { return false; } if (this.enabled != other.enabled) { return false; } if (this.visible != other.visible) { return false; } if (this.selectOnly != other.selectOnly) { return false; } if (this.movable != other.movable) { return false; } if (this.resizable != other.resizable) { return false; } if (this.sortable != other.sortable) { return false; } if ((this.title == null) ? (other.title != null) : !this.title.equals(other.title)) { return false; } if ((this.background == null) ? (other.background != null) : !this.background.equals(other.background)) { return false; } if ((this.foreground == null) ? (other.foreground != null) : !this.foreground.equals(other.foreground)) { return false; } if ((this.font == null) ? (other.font != null) : !this.font.equals(other.font)) { return false; } return true; } public boolean isEqual(Object obj) { if (obj == null) { return false; } if (obj.getClass() != this.getClass()) { return false; } if (!lightEquals(obj)) { return false; } final GridColumnsNode other = (GridColumnsNode) obj; if (this.children != other.children && (this.children == null || !isColumnsEquals(this.children, other.children))) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 37 * hash + this.minWidth; hash = 37 * hash + this.maxWidth; hash = 37 * hash + (this.readonly ? 1 : 0); hash = 37 * hash + (this.enabled ? 1 : 0); hash = 37 * hash + (this.visible ? 1 : 0); hash = 37 * hash + (this.title != null ? this.title.hashCode() : 0); hash = 37 * hash + (this.background != null ? this.background.hashCode() : 0); hash = 37 * hash + (this.foreground != null ? this.foreground.hashCode() : 0); hash = 37 * hash + (this.font != null ? this.font.hashCode() : 0); hash = 37 * hash + (this.selectOnly ? 1 : 0); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } return super.equals(obj); } public static boolean isColumnsEquals(List<GridColumnsNode> first, List<GridColumnsNode> second) { if (first != second) { if (first != null && second != null) { if (first.size() == second.size()) { for (int i = 0; i < first.size(); i++) { GridColumnsNode fColumn = first.get(i); GridColumnsNode sColumn = second.get(i); if (fColumn != sColumn) { if (fColumn != null && sColumn != null) { if (!fColumn.equals(sColumn)) { return false; } } else { return false; } } } } else { return false; } } else { return false; } } return true; } public void assign(GridColumnsNode aSource) throws Exception { lightAssign(aSource); children = new ArrayList<>(); if (aSource != null && aSource.getChildren() != null) { List<GridColumnsNode> lchildren = aSource.getChildren(); for (int i = 0; i < lchildren.size(); i++) { if (lchildren.get(i) != null) { GridColumnsNode newCol = lchildren.get(i).copy(); children.add(newCol); newCol.setParent(this); } else { children.add(null); } } assert children.size() == lchildren.size(); } } public GridColumnsNode lightCopy() { GridColumnsNode copied = new GridColumnsNode(); copied.lightAssign(this); return copied; } public GridColumnsNode copy() throws Exception { GridColumnsNode copied = new GridColumnsNode(); copied.assign(this); return copied; } public int getWidth() { if (tableColumn != null) { return tableColumn.getWidth(); } else { int pWidth = 0; for (int i = 0; i < children.size(); i++) { pWidth += children.get(i).getWidth(); } return pWidth; } } public void setWidth(int aValue) { if (tableColumn != null) { tableColumn.setWidth(aValue); } } public int getPreferredWidth() { if (tableColumn != null) { return tableColumn.getPreferredWidth(); } else { return 0; } } public void setPreferredWidth(int aValue) { if (tableColumn != null) { tableColumn.setPreferredWidth(aValue); } } public int getMinWidth() { if (tableColumn != null) { return tableColumn.getMinWidth(); } else { return minWidth; } } public void setMinWidth(int aValue) { if (tableColumn != null) { tableColumn.setMinWidth(aValue); } else { minWidth = aValue; } } public int getMaxWidth() { if (tableColumn != null) { return tableColumn.getMaxWidth(); } else { return maxWidth; } } public void setMaxWidth(int aValue) { if (tableColumn != null) { tableColumn.setMaxWidth(aValue); } else { maxWidth = aValue; } } public List<GridColumnsNode> getChildren() { return children; } public void setChildren(List<GridColumnsNode> aChildren) { children = aChildren; if (children != null) { children.stream().forEach((lcol) -> { lcol.setParent(this); }); } else { children = new ArrayList<>(); } } public boolean hasChildren() { return children != null && !children.isEmpty(); } public boolean isSelectOnly() { return selectOnly; } public void setSelectOnly(boolean aValue) { selectOnly = aValue; } public boolean isReadonly() { return readonly; } public void setReadonly(boolean aValue) { readonly = aValue; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean aValue) { enabled = aValue; } public boolean isVisible() { return visible; } public void setVisible(boolean aValue) { visible = aValue; } public boolean isMovable() { return movable; } public void setMovable(boolean aValue) { movable = aValue; } public boolean isResizable() { return resizable; } public void setResizable(boolean aValue) { resizable = aValue; } public boolean isSortable() { return sortable; } public void setSortable(boolean aValue) { sortable = aValue; } public String getTitle() { if (tableColumn != null) { if (tableColumn.getHeaderValue() instanceof String) { return (String) tableColumn.getHeaderValue(); } else { return title; } } else { return title; } } public void setTitle(String aTitle) { if (tableColumn != null) { tableColumn.setHeaderValue(aTitle); } else { if (title == null ? aTitle != null : !title.equals(aTitle)) { String oldTtile = title; title = aTitle; changeSupport.firePropertyChange("title", oldTtile, title); } } } public Color getBackground() { return background; } public void setBackground(Color aValue) { Color oldValue = background; background = aValue; changeSupport.firePropertyChange("background", oldValue, aValue); } @Override public void removeColumnNode(GridColumnsNode aNode) { if (children != null) { children.remove(aNode); aNode.getChangeSupport().removePropertyChangeListener("children", childrenListener); changeSupport.firePropertyChange("children", null, children); } } @Override public void addColumnNode(GridColumnsNode aNode) { if (children == null) { children = new ArrayList<>(); } if (!children.contains(aNode)) { children.add(aNode); aNode.setParent(this); aNode.getChangeSupport().addPropertyChangeListener("children", childrenListener); changeSupport.firePropertyChange("children", null, children); } } @Override public void insertColumnNode(int atIndex, GridColumnsNode aNode) { if (children == null) { children = new ArrayList<>(); } if (!children.contains(aNode) && atIndex >= 0 && atIndex <= children.size()) { children.add(atIndex, aNode); aNode.setParent(this); aNode.getChangeSupport().addPropertyChangeListener("children", childrenListener); changeSupport.firePropertyChange("children", null, children); } } public Color getForeground() { return foreground; } public void setForeground(Color aValue) { Color oldValue = foreground; foreground = aValue; changeSupport.firePropertyChange("foreground", oldValue, aValue); } public Font getFont() { return font; } public void setFont(Font aValue) { Font oldValue = font; font = aValue; changeSupport.firePropertyChange("font", oldValue, aValue); } public boolean isLeaf() { return children.isEmpty(); } }