001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.pm.graphic.spreadsheet.renderer;
051:
052: import java.awt.Color;
053: import java.awt.Component;
054: import java.awt.Dimension;
055: import java.awt.Font;
056: import java.awt.Point;
057: import java.awt.Rectangle;
058:
059: import javax.swing.BorderFactory;
060: import javax.swing.Box;
061: import javax.swing.BoxLayout;
062: import javax.swing.ImageIcon;
063: import javax.swing.JComponent;
064: import javax.swing.JLabel;
065: import javax.swing.JPanel;
066: import javax.swing.JTable;
067: import javax.swing.JTextField;
068: import javax.swing.text.JTextComponent;
069:
070: import com.projity.graphic.configuration.CellFormat;
071: import com.projity.pm.graphic.ChangeAwareTextField;
072: import com.projity.pm.graphic.IconManager;
073: import com.projity.pm.graphic.model.cache.GraphicNode;
074: import com.projity.pm.graphic.spreadsheet.SpreadSheetParams;
075: import com.projity.pm.graphic.spreadsheet.common.CommonSpreadSheetModel;
076:
077: /**
078: *
079: */
080: public class NameCellComponent extends JPanel {
081: protected JComponent textComponent = null;
082: protected JLabel iconLabel = null;
083: protected Box.Filler filler = null;
084: protected ImageIcon collapsedIcon;
085: protected ImageIcon expandedIcon;
086: protected ImageIcon leafIcon;
087: protected ImageIcon emptyLeafIcon;
088: protected String text = null;
089: protected ImageIcon icon = null;
090: protected boolean lazy = false;
091: protected boolean fetched = true;
092: protected ImageIcon unfetchedLazyIcon = null;
093: protected ImageIcon fetchedLazyExpandedIcon = null;
094: protected ImageIcon fetchedLazyCollapsedIcon = null;
095: protected boolean offline;
096:
097: /**
098: *
099: */
100: public NameCellComponent() {
101: this (new JLabel(""));
102: }
103:
104: /**
105: * textComponent is a JLabel or a JTextComponent
106: */
107: public NameCellComponent(JComponent textComponent) {
108: super ();
109: this .textComponent = textComponent;
110: textComponent.setFont(getFont());
111: }
112:
113: public void init() {
114: setBackground(Color.WHITE);
115: textComponent.setBorder(BorderFactory.createEmptyBorder(0, 2,
116: 0, 0));
117: setLayout(new BoxLayout(this , BoxLayout.X_AXIS));
118: if (getComponentCount() != 0)
119: removeAll();
120: leafIcon = IconManager.getIcon("spreadsheet.leaf.icon");
121: emptyLeafIcon = IconManager
122: .getIcon("spreadsheet.emptyleaf.icon");
123: collapsedIcon = IconManager
124: .getIcon("spreadsheet.collapsed.icon");
125: expandedIcon = IconManager.getIcon("spreadsheet.expanded.icon");
126:
127: unfetchedLazyIcon = IconManager
128: .getIcon("spreadsheet.unfetchedLazy.icon");
129: fetchedLazyExpandedIcon = IconManager
130: .getIcon("spreadsheet.fetchedLazyExpanded.icon");
131: fetchedLazyCollapsedIcon = IconManager
132: .getIcon("spreadsheet.fetchedLazyCollapsed.icon");
133:
134: filler = (Box.Filler) Box.createHorizontalStrut(leafIcon
135: .getIconWidth());
136: add(filler);
137: iconLabel = new JLabel(leafIcon);
138: iconLabel.setAlignmentY(Component.CENTER_ALIGNMENT);
139: iconLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
140: add(iconLabel);
141: add(textComponent);
142: }
143:
144: public boolean isOffline() {
145: return offline;
146: }
147:
148: public void setOffline(boolean offline) {
149: this .offline = offline;
150: }
151:
152: /**
153: * @return Returns the text component.
154: */
155: public JComponent getTextComponent() {
156: return textComponent;
157: }
158:
159: /**
160: * @return Returns the label.
161: */
162: public JLabel getIconLabel() {
163: return iconLabel;
164: }
165:
166: public void setText(String text) {
167: if (this .text == text)
168: return;
169: this .text = text;
170: if (textComponent instanceof JLabel)
171: ((JLabel) textComponent).setText(text);
172: else if (textComponent instanceof JTextComponent)
173: ((JTextComponent) textComponent).setText(text);
174: }
175:
176: public String getText() {
177: if (textComponent instanceof JLabel)
178: return ((JLabel) textComponent).getText();
179: else if (textComponent instanceof JTextComponent)
180: return ((JTextComponent) textComponent).getText();
181: else
182: return null;
183: }
184:
185: public void setFont(Font font) {
186: super .setFont(font);
187: if (textComponent != null)
188: textComponent.setFont(font);
189: }
190:
191: public void setLeaf(boolean empty) {
192: ImageIcon askedIcon = (empty) ? emptyLeafIcon : leafIcon;
193: if (icon == askedIcon)
194: return;
195: icon = askedIcon;
196: iconLabel.setIcon(icon);
197: }
198:
199: public void setCollapsed(boolean value) {
200: ImageIcon askedIcon = null;
201: if (isLazy()) {
202: if (isFetched())
203: askedIcon = (value) ? fetchedLazyCollapsedIcon
204: : fetchedLazyExpandedIcon;
205: else
206: askedIcon = unfetchedLazyIcon;
207: } else {
208: askedIcon = (value) ? collapsedIcon : expandedIcon;
209: }
210: if (icon == askedIcon)
211: return;
212: icon = askedIcon;
213: iconLabel.setIcon(icon);
214: }
215:
216: public boolean isLeaf() {
217: return (icon == leafIcon);
218: }
219:
220: public boolean isCollapsed() {
221: return (icon == collapsedIcon || icon == unfetchedLazyIcon || icon == fetchedLazyCollapsedIcon);
222: }
223:
224: public void setLevel(int level) {
225: setLevel(level, false);
226: }
227:
228: int level = -1;
229:
230: public void setLevel(int level, boolean offline) {
231: if (this .level == level)
232: return;
233: this .level = level;
234: if (level == 0)
235: return;
236: int width = (leafIcon == null) ? 0 : (level - 1)
237: * leafIcon.getIconWidth();
238: filler.changeShape(new Dimension(width, 0), new Dimension(
239: width, 0), new Dimension(width, Short.MAX_VALUE));
240: if (offline)
241: invalidate(); //needed for offline, otherwise filler don't change
242: }
243:
244: public static NameCellComponent getInstance() {
245: NameCellComponent instance = new NameCellComponent();
246: instance.init();
247: return instance;
248: //problem in icon position in isOnIcon when reusing the same instance
249: }
250:
251: public static boolean isOnIcon(Point pos, Dimension cellSize,
252: int level) {
253: NameCellComponent reference = getInstance();
254: reference.setSize(cellSize);
255: reference.setLevel(level);
256: reference.doLayout();
257: Rectangle bounds = reference.getIconLabel().getBounds();
258: return bounds.contains(pos);
259: }
260:
261: public static boolean isOnText(Point pos, Dimension cellSize,
262: int level) {
263: NameCellComponent reference = getInstance();
264: reference.setSize(cellSize);
265: reference.setLevel(level);
266: reference.doLayout();
267: return reference.getTextComponent().getBounds().contains(pos);
268: }
269:
270: protected static NameCellComponent rendererComponent;
271: protected static NameCellComponent editorComponent;
272: protected static Font savedRendererFont, savedEditorFont;
273:
274: protected static NameCellComponent getUninitializedComponent(
275: boolean hasFocus) {
276: if (hasFocus) {
277: if (editorComponent == null) {
278: JComponent textComponent = new JTextField();
279: editorComponent = new NameCellComponent(textComponent);
280: savedEditorFont = editorComponent.getFont();
281: textComponent.setBorder(null);
282: editorComponent.init();
283: } else
284: editorComponent.setFont(savedEditorFont);
285: return editorComponent;
286: } else {
287: if (rendererComponent == null) {
288: JComponent textComponent = new JLabel();
289: rendererComponent = new NameCellComponent(textComponent);
290: savedRendererFont = rendererComponent.getFont();
291: textComponent.setBorder(null);
292: rendererComponent.init();
293: } else
294: rendererComponent.setFont(savedRendererFont);
295: return rendererComponent;
296:
297: }
298: }
299:
300: public static NameCellComponent getComponent(JTable table,
301: Object value, boolean isSelected, boolean hasFocus,
302: int row, int column) {
303: NameCellComponent component = getUninitializedComponent(hasFocus);
304: //JComponent textComponent=component.getTextComponent();
305:
306: // CellUtility.setAppearance(table, value, isSelected, hasFocus, row,
307: // column, textComponent);
308: component.setOffline(false);
309: CellUtility.setAppearance(table, value, isSelected, hasFocus,
310: row, column, component);
311: CommonSpreadSheetModel model = (CommonSpreadSheetModel) table
312: .getModel();
313: GraphicNode node = model.getNode(row);
314: component.setText(value == null ? "" : value.toString());
315: int level = model.getCache().getLevel(node);
316: component.setLevel((node.isVoid()) ? (level + 1) : level);
317: component.setLazy(node.isLazyParent());
318: component.setFetched(node.isFetched());
319: if (model.getCellProperties(node).isCompositeIcon()) {
320: component.setCollapsed(node.isCollapsed());
321: } else {
322: component.setLeaf(node.isVoid());
323: }
324: FontManager.setComponentFont(model.getCellProperties(node),
325: component);
326: component.doLayout();
327: return component;
328: }
329:
330: public static Component getComponent(Object value,
331: GraphicNode node, SpreadSheetParams params) {
332: NameCellComponent component = getUninitializedComponent(false);
333: CellFormat format = params.getFieldArray().getCellStyle()
334: .getCellFormat(node);
335: component.getTextComponent().setBorder(null);
336: component.setOffline(true);
337: CellUtility.setAppearance(format, component);
338: String valueS = value == null ? " " : value.toString();//to avoid void textComponents with no height
339: if (valueS.length() == 0)
340: valueS = " ";
341: component.setText(valueS);
342: int level = params.getCache().getLevel(node);
343: component.setLevel((node.isVoid()) ? (level + 1) : level, true);
344: component.setLazy(node.isLazyParent());
345: component.setFetched(node.isFetched());
346: if (format.isCompositeIcon()) {
347: component.setCollapsed(node.isCollapsed());
348: } else {
349: component.setLeaf(node.isVoid());
350: }
351: FontManager.setComponentFont(format, component);
352: return component;
353: }
354:
355: public void doLayout() {
356: super .doLayout();
357: if (offline) {
358: textComponent.setSize(getWidth() - textComponent.getX(),
359: textComponent.getHeight());
360: }
361: }
362:
363: /* (non-Javadoc)
364: * @see java.awt.Component#setBackground(java.awt.Color)
365: */
366: public void setBackground(Color bg) {
367: super .setBackground(bg);
368: if (textComponent != null)
369: textComponent.setBackground(bg);
370: }
371:
372: /* (non-Javadoc)
373: * @see java.awt.Component#setForeground(java.awt.Color)
374: */
375: public void setForeground(Color fg) {
376: super .setForeground(fg);
377: if (textComponent != null)
378: textComponent.setForeground(fg);
379: }
380:
381: public void requestFocus() {
382: if (textComponent instanceof ChangeAwareTextField) {
383: textComponent.setVisible(true);
384: textComponent.setEnabled(true);
385: textComponent.setFocusable(true);
386: textComponent.requestFocus();
387: System.out
388: .println("delegating focus request to text component");
389: }
390: }
391:
392: /*public boolean requestFocus(boolean temporary) {
393: return textComponent.requestFocus(temporary);
394: }
395: public boolean requestFocusInWindow() {
396: return textComponent.requestFocusInWindow();
397: }*/
398: public final boolean isLazy() {
399: return lazy;
400: }
401:
402: public final void setLazy(boolean lazy) {
403: this .lazy = lazy;
404: }
405:
406: public final boolean isFetched() {
407: return fetched;
408: }
409:
410: public final void setFetched(boolean fetched) {
411: this.fetched = fetched;
412: }
413:
414: }
|