QedeqTreeCellRenderer.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2013,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.gui.se.tree;
017 
018 import java.awt.Component;
019 import java.awt.Graphics;
020 
021 import javax.swing.Icon;
022 import javax.swing.ImageIcon;
023 import javax.swing.JTree;
024 import javax.swing.tree.DefaultMutableTreeNode;
025 import javax.swing.tree.DefaultTreeCellRenderer;
026 
027 import org.qedeq.base.trace.Trace;
028 import org.qedeq.kernel.bo.common.QedeqBo;
029 import org.qedeq.kernel.se.common.DependencyState;
030 import org.qedeq.kernel.se.common.LoadingState;
031 import org.qedeq.kernel.se.common.LogicalModuleState;
032 
033 /**
034  * Renderer for a JTree.
035  *
036  @version $Revision: 1.8 $
037  @author  Michael Meyling
038  */
039 public final class QedeqTreeCellRenderer extends DefaultTreeCellRenderer {
040 
041     /** This class. */
042     private static final Class CLASS = QedeqTreeCellRenderer.class;
043 
044     /** Status icon. */
045     private static ImageIcon webLoadingIcon = new ImageIcon(
046         QedeqTreeCellRenderer.class.getResource(
047             "/images/qedeq/16x16/module_web_loading.gif"));
048 
049     /** Status icon. */
050     private static ImageIcon webLoadingErrorIcon = new ImageIcon(
051         QedeqTreeCellRenderer.class.getResource(
052             "/images/qedeq/16x16/module_web_loading_error.gif"));
053 
054     /** Status icon. */
055     private static ImageIcon fileLoadingIcon = new ImageIcon(
056         QedeqTreeCellRenderer.class.getResource(
057             "/images/qedeq/16x16/module_file_loading.gif"));
058 
059     /** Status icon. */
060     private static ImageIcon fileLoadingErrorIcon = new ImageIcon(
061         QedeqTreeCellRenderer.class.getResource(
062             "/images/qedeq/16x16/module_file_loading_error.gif"));
063 
064     /** Status icon. */
065     private static ImageIcon memoryLoadingIcon = new ImageIcon(
066         QedeqTreeCellRenderer.class.getResource(
067             "/images/qedeq/16x16/module_memory_loading.gif"));
068 
069     /** Status icon. */
070     private static ImageIcon memoryLoadingErrorIcon = new ImageIcon(
071         QedeqTreeCellRenderer.class.getResource(
072             "/images/qedeq/16x16/module_memory_loading_error.gif"));
073 
074     /** Status icon. */
075     private static ImageIcon loadedIcon = new ImageIcon(
076         QedeqTreeCellRenderer.class.getResource(
077             "/images/qedeq/16x16/module_loaded.gif"));
078 
079     /** Status icon. */
080     private static ImageIcon loadingRequiredIcon = new ImageIcon(
081         QedeqTreeCellRenderer.class.getResource(
082             "/images/qedeq/16x16/module_loading_required.gif"));
083 
084     /** Status icon. */
085     private static ImageIcon loadingRequiredErrorIcon = new ImageIcon(
086         QedeqTreeCellRenderer.class.getResource(
087             "/images/qedeq/16x16/module_loading_required_error.gif"));
088 
089     /** Status icon. */
090     private static ImageIcon loadedRequiredIcon = new ImageIcon(
091         QedeqTreeCellRenderer.class.getResource(
092             "/images/qedeq/16x16/module_loaded_required.gif"));
093 
094     /** Status icon. */
095     private static ImageIcon checkingRequiredIcon = new ImageIcon(
096         QedeqTreeCellRenderer.class.getResource(
097             "/images/qedeq/16x16/module_checking_required.gif"));
098 
099     /** Status icon. */
100     private static ImageIcon checkingRequiredErrorIcon = new ImageIcon(
101         QedeqTreeCellRenderer.class.getResource(
102             "/images/qedeq/16x16/module_checking_required_error.gif"));
103 
104     /** Status icon. */
105     private static ImageIcon checkingIcon = new ImageIcon(
106         QedeqTreeCellRenderer.class.getResource(
107             "/images/qedeq/16x16/module_checking.gif"));
108 
109     /** Status icon. */
110     private static ImageIcon checkingErrorIcon = new ImageIcon(
111         QedeqTreeCellRenderer.class.getResource(
112             "/images/qedeq/16x16/module_checking_error.gif"));
113 
114     /** Status icon. */
115     private static ImageIcon checkedIcon = new ImageIcon(
116         QedeqTreeCellRenderer.class.getResource(
117             "/images/qedeq/16x16/module_checked.gif"));
118 
119     /** Status icon. */
120     private static ImageIcon warningsIcon = new ImageIcon(
121         QedeqTreeCellRenderer.class.getResource(
122             "/images/qedeq/16x16/module_warnings.gif"));
123 
124     /** Status icon. */
125     private static ImageIcon errorsIcon = new ImageIcon(
126         QedeqTreeCellRenderer.class.getResource(
127             "/images/qedeq/16x16/module_errors.gif"));
128 
129 
130 // LATER mime 20080502: do we want to leave it for our alternative "paint" or do we delete it?
131 //
132 //    /** Color to use for the foreground for selected nodes. */
133 //    private Color textSelectionColor = UIManager.getColor("Tree.selectionForeground");
134 //
135 //    /** Color to use for the foreground for non-selected nodes. */
136 //    private Color textNonSelectionColor = UIManager.getColor("Tree.textForeground");
137 //
138 //    /** Color to use for the background when a node is selected. */
139 //    private Color backgroundSelectionColor = UIManager.getColor("Tree.selectionBackground");
140 //
141 //    /** Color to use for the background when the node isn't selected. */
142 //    private Color backgroundNonSelectionColor = UIManager.getColor("Tree.textBackground");
143 
144     public QedeqTreeCellRenderer() {
145         super();
146     }
147 
148     public synchronized Component getTreeCellRendererComponent(final JTree tree,
149             final Object value, final boolean isSelected,
150             final boolean expanded, final boolean leaf, final int row,
151             final boolean hasFocus) {
152 
153         final String method = "getTreeCellRendererComponent";
154         Trace.param(CLASS, this, method, row + " is selected", isSelected);
155         Trace.param(CLASS, this, method, row + " is expanded", expanded);
156         Trace.param(CLASS, this, method, row + " hasFocus", hasFocus);
157         Trace.param(CLASS, this, method, row + " leaf", leaf);
158         Trace.param(CLASS, this, method, row + " maxSelectionRow", tree.getMaxSelectionRow());
159         Trace.param(CLASS, this, method, row + " selectionCount", tree.getSelectionCount());
160         Trace.param(CLASS, this, method, row + " rowCount", tree.getRowCount());
161         Trace.param(CLASS, this, method, row + " tree path", tree.getPathForRow(row));
162 
163         ModuleElement unit;
164         QedeqBo prop;
165 /* m31 20080502: Debugging code
166         TreeModel model = tree.getModel();
167         BasicTreeUI ui = (BasicTreeUI) tree.getUI();
168         VariableHeightLayoutCache vhlc = null;
169         Vector visibleNodes = null;
170         try {
171             vhlc = (VariableHeightLayoutCache) IoUtility.getFieldContentSuper(ui, "treeState");
172             visibleNodes = (Vector) IoUtility.getFieldContentSuper(vhlc, "visibleNodes");
173             System.out.println("vectorSize = " + visibleNodes.size());
174             for (int i = 0; i < visibleNodes.size(); i++) {
175                 System.out.println("  " + visibleNodes.get(i));
176             }
177         } catch (Throwable e) {
178             e.printStackTrace();
179         }
180 */
181         super.getTreeCellRendererComponent(
182             tree, value, isSelected, expanded, leaf, row, hasFocus);
183         if (value instanceof DefaultMutableTreeNode) {
184             if (((DefaultMutableTreeNodevalue).getUserObject()
185                     instanceof ModuleElement) {
186                 unit = (ModuleElement) ((DefaultMutableTreeNode)
187                     value).getUserObject();
188                 setText(unit.getName());
189             else {
190                 prop = (QedeqBo) ((DefaultMutableTreeNode)
191                     value).getUserObject();
192                 String text = prop.getName();
193                 setText(text);
194                 final LoadingState loadingState = prop.getLoadingState();
195                 final DependencyState dependencyState = prop.getDependencyState();
196                 final LogicalModuleState logicalState = prop.getLogicalState();
197 
198                 if (loadingState == LoadingState.STATE_LOADED) {
199                     setToolTipText(prop.getUrl().toString());
200                 else {
201                     setToolTipText(prop.getStateDescription());
202                 }
203 
204                 setIcon(null);
205                 if (loadingState == LoadingState.STATE_DELETED) {
206                     // do nothing;
207                 else if (loadingState == LoadingState.STATE_LOADING_FROM_WEB) {
208                     setIcon(webLoadingIcon);
209                 else if (loadingState == LoadingState.STATE_LOADING_FROM_WEB_FAILED) {
210                     setIcon(webLoadingErrorIcon);
211                 else if (loadingState == LoadingState.STATE_LOADING_FROM_LOCAL_FILE) {
212                     setIcon(fileLoadingIcon);
213                 else if (loadingState == LoadingState.STATE_LOADING_FROM_LOCAL_FILE_FAILED) {
214                     setIcon(fileLoadingErrorIcon);
215                 else if (loadingState == LoadingState.STATE_LOADING_FROM_BUFFER) {
216                     setIcon(fileLoadingIcon);
217                 else if (loadingState == LoadingState.STATE_LOADING_FROM_BUFFER_FAILED) {
218                     setIcon(fileLoadingErrorIcon);
219                 else if (loadingState == LoadingState.STATE_LOADING_INTO_MEMORY) {
220                     setIcon(memoryLoadingIcon);
221                 else if (loadingState == LoadingState.STATE_LOADING_INTO_MEMORY_FAILED) {
222                     setIcon(memoryLoadingErrorIcon);
223                 else if (loadingState == LoadingState.STATE_LOADED) {
224                     setPositiveIcon(prop, loadedIcon);
225                     if (dependencyState != DependencyState.STATE_UNDEFINED) {
226                         if (dependencyState
227                                 == DependencyState.STATE_LOADING_REQUIRED_MODULES) {
228                             setIcon(loadingRequiredIcon);
229                         else if (dependencyState
230                                 == DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED) {
231                             setIcon(loadingRequiredErrorIcon);
232                         else if (dependencyState
233                                 == DependencyState.STATE_LOADED_REQUIRED_MODULES) {
234                             setPositiveIcon(prop, loadedRequiredIcon);
235                             if (logicalState != LogicalModuleState.STATE_UNCHECKED) {
236                                 if (logicalState == LogicalModuleState.STATE_EXTERNAL_CHECKING) {
237                                     setPositiveIcon(prop, checkingRequiredIcon);
238                                 else if (logicalState
239                                         == LogicalModuleState.STATE_EXTERNAL_CHECKING_FAILED) {
240                                     setIcon(checkingRequiredErrorIcon);
241                                 else if (logicalState == LogicalModuleState.STATE_INTERNAL_CHECKING) {
242                                     setPositiveIcon(prop, checkingIcon);
243                                 else if (logicalState
244                                         == LogicalModuleState.STATE_INTERNAL_CHECKING_FAILED) {
245                                     setIcon(checkingErrorIcon);
246                                 else if (logicalState == LogicalModuleState.STATE_CHECKED) {
247                                     setPositiveIcon(prop, checkedIcon);
248                                 else {    // unknown logical state
249                                     throw new IllegalStateException("unknown module state: "
250                                         + logicalState.getText());
251                                 }
252                             }
253                         else {    // unknown dependency state
254                             throw new IllegalStateException("unknown module state: "
255                                 + dependencyState.getText());
256                         }
257                     }
258                 else {    // unknown loading state
259                     throw new IllegalStateException("unknown module state: "
260                         + loadingState.getText());
261                 }
262             }
263         }
264     // LATER m31 20080502: do we want to leave it for our alternative "paint" or do we delete it?
265 /*
266         if (isSelected) {
267             setBackground(backgroundSelectionColor);
268             setForeground(textSelectionColor);
269         } else {
270             setBackground(backgroundNonSelectionColor);
271             setForeground(textNonSelectionColor);
272         }
273 */
274 // mime 20080430: comment out, debug code!
275 //        Trace.trace(CLASS, this, method, "-- global info");
276 //        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getModel().getRoot();
277 //        Trace.param(CLASS, this, method, "-- child", node.getChildCount());
278 //        for (int i = 0; i < node.getChildCount(); i++) {
279 //            Trace.param(CLASS, this, method, "--- node" + i,  node.getChildAt(i));
280 //            Trace.param(CLASS, this, method, "--- child count" + i,
281 //                node.getChildAt(i).getChildCount());
282 //        }
283 
284         return this;
285     }
286 
287     // LATER m31 20080502: do we want to rename it back to "paint" or do we delete it?
288     /*
289      * paint is subclassed to draw the background correctly.  JLabel
290      * currently does not allow backgrounds other than white, and it
291      * will also fill behind the icon. Something that isn't desirable.
292      */
293    public void paintttttt(final Graphics g) {
294        final String method = "paint";
295        Trace.param(CLASS, this, method, "label", getText());
296        Icon currentI = getIcon();
297        if (currentI != null && getText() != null) {
298            int offset = (currentI.getIconWidth() + getIconTextGap());
299            g.setColor(getBackground());
300            if (getComponentOrientation().isLeftToRight()) {
301                 g.fillRect(offset, 0, getWidth() - offset, getHeight() 1);
302            else {
303                 g.fillRect(00, getWidth() - offset, getHeight() 1);
304            }
305        else {
306            g.fillRect(00, getWidth() 1, getHeight() 1);
307        }
308        super.paint(g);
309     }
310 
311     private void setPositiveIcon(final QedeqBo qedeq, final Icon icon) {
312         if (qedeq.hasErrors()) {
313             setIcon(errorsIcon);
314         else if (qedeq.hasWarnings()) {
315             setIcon(warningsIcon);
316         else {
317             setIcon(icon);
318         }
319     }
320 
321 }