001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU General
007: * Public License Version 2 only ("GPL") or the Common Development and Distribution
008: * License("CDDL") (collectively, the "License"). You may not use this file except in
009: * compliance with the License. You can obtain a copy of the License at
010: * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
011: * License for the specific language governing permissions and limitations under the
012: * License. When distributing the software, include this License Header Notice in
013: * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun
014: * designates this particular file as subject to the "Classpath" exception as
015: * provided by Sun in the GPL Version 2 section of the License file that
016: * accompanied this code. If applicable, add the following below the License Header,
017: * with the fields enclosed by brackets [] replaced by your own identifying
018: * information: "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Contributor(s):
021: *
022: * The Original Software is NetBeans. The Initial Developer of the Original Software
023: * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
024: * Rights Reserved.
025: *
026: * If you wish your version of this file to be governed by only the CDDL or only the
027: * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
028: * this software in this distribution under the [CDDL or GPL Version 2] license." If
029: * you do not indicate a single choice of license, a recipient has the option to
030: * distribute your version of this file under either the CDDL, the GPL Version 2 or
031: * to extend the choice of license to its licensees as provided above. However, if
032: * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
033: * the option applies only if the new code is made subject to such option by the
034: * copyright holder.
035: */
036:
037: package org.netbeans.installer.wizard.utils;
038:
039: import java.awt.Component;
040: import java.awt.Dimension;
041: import java.awt.GridBagConstraints;
042: import java.awt.GridBagLayout;
043: import java.awt.Insets;
044: import java.util.ArrayList;
045: import java.util.HashMap;
046: import java.util.List;
047: import java.util.Map;
048: import javax.swing.JLabel;
049: import javax.swing.JTable;
050: import javax.swing.JTree;
051: import javax.swing.border.EmptyBorder;
052: import javax.swing.event.TreeModelListener;
053: import javax.swing.table.TableCellRenderer;
054: import javax.swing.tree.TreeModel;
055: import javax.swing.tree.TreePath;
056: import org.netbeans.installer.utils.ResourceUtils;
057: import org.netbeans.installer.utils.helper.DetailedStatus;
058: import org.netbeans.installer.product.components.Product;
059: import org.netbeans.installer.product.Registry;
060: import org.netbeans.installer.utils.helper.ErrorLevel;
061: import org.netbeans.installer.utils.LogManager;
062: import org.netbeans.installer.utils.helper.swing.NbiDialog;
063: import org.netbeans.installer.utils.helper.swing.NbiScrollPane;
064: import org.netbeans.installer.utils.helper.swing.NbiTreeTableColumnCellRenderer;
065: import org.netbeans.installer.utils.helper.swing.NbiTreeTable;
066: import org.netbeans.installer.utils.helper.swing.NbiTreeTableModel;
067:
068: public class InstallationDetailsDialog extends NbiDialog {
069: private NbiTreeTable detailsTreeTable;
070: private NbiScrollPane detailsScrollPane;
071: private static final String TITLE_INSTALLATION_DETAILS_KEY = "IDD.installation.details.label";
072: private static final String TITLE_COMPONENTS_KEY = "IDD.component.label";
073: private static final String TITLE_STATUS_KEY = "IDD.status.label";
074:
075: public InstallationDetailsDialog() {
076: super ();
077:
078: initComponents();
079: initialize();
080: }
081:
082: private void initialize() {
083: setTitle(ResourceUtils.getString(
084: InstallationDetailsDialog.class,
085: TITLE_INSTALLATION_DETAILS_KEY));
086: }
087:
088: private void initComponents() {
089: setLayout(new GridBagLayout());
090:
091: detailsTreeTable = new NbiTreeTable(
092: new InstallationDetailsTreeTableModel());
093: detailsTreeTable.setShowVerticalLines(false);
094: detailsTreeTable.setOpaque(false);
095: detailsTreeTable.setTableHeader(null);
096: detailsTreeTable
097: .setRowHeight(detailsTreeTable.getRowHeight() + 4);
098: detailsTreeTable.setIntercellSpacing(new Dimension(0, 0));
099: detailsTreeTable
100: .setTreeColumnCellRenderer(new InstallationDetailsTreeColumnCellRenderer(
101: detailsTreeTable));
102: detailsTreeTable.getColumnModel().getColumn(1).setMaxWidth(200);
103: detailsTreeTable.getColumnModel().getColumn(1).setMinWidth(200);
104: detailsTreeTable.getColumnModel().getColumn(1).setCellRenderer(
105: new InstallationStatusCellRenderer());
106: detailsTreeTable.setRowSelectionAllowed(false);
107: detailsTreeTable.setColumnSelectionAllowed(false);
108: detailsTreeTable.setCellSelectionEnabled(false);
109:
110: detailsScrollPane = new NbiScrollPane(detailsTreeTable);
111:
112: add(detailsScrollPane, new GridBagConstraints(0, 0, 1, 1, 1.0,
113: 1.0, GridBagConstraints.CENTER,
114: GridBagConstraints.BOTH, new Insets(11, 11, 11, 11), 0,
115: 0));
116: }
117:
118: private static class InstallationDetailsTreeModel implements
119: TreeModel {
120: private List<Product> components = new ArrayList<Product>();
121: private Map<Product, List<String>> propertiesMap = new HashMap<Product, List<String>>();
122:
123: private Object root = new Object();
124:
125: public InstallationDetailsTreeModel() {
126: final Registry registry = Registry.getInstance();
127:
128: components
129: .addAll(registry
130: .getProducts(DetailedStatus.INSTALLED_SUCCESSFULLY));
131: components
132: .addAll(registry
133: .getProducts(DetailedStatus.INSTALLED_WITH_WARNINGS));
134: components.addAll(registry
135: .getProducts(DetailedStatus.FAILED_TO_INSTALL));
136:
137: components
138: .addAll(registry
139: .getProducts(DetailedStatus.UNINSTALLED_SUCCESSFULLY));
140: components
141: .addAll(registry
142: .getProducts(DetailedStatus.UNINSTALLED_WITH_WARNINGS));
143: components.addAll(registry
144: .getProducts(DetailedStatus.FAILED_TO_UNINSTALL));
145: }
146:
147: public Object getRoot() {
148: return root;
149: }
150:
151: public Object getChild(Object parent, int index) {
152: if (parent.equals(root)) {
153: return components.get(index);
154: } else {
155: if (parent instanceof Product) {
156: initComponentProperties((Product) parent);
157: return propertiesMap.get(parent).get(index);
158: } else {
159: return null;
160: }
161: }
162: }
163:
164: public int getChildCount(Object parent) {
165: if (parent.equals(root)) {
166: return components.size();
167: }
168:
169: if (parent instanceof Product) {
170: initComponentProperties((Product) parent);
171: return propertiesMap.get(parent).size();
172: } else {
173: return 0;
174: }
175: }
176:
177: private void initComponentProperties(Product component) {
178: List<String> properties = propertiesMap.get(component);
179: if (properties == null) {
180: properties = new ArrayList<String>();
181:
182: switch (component.getDetailedStatus()) {
183: case INSTALLED_WITH_WARNINGS:
184: for (Throwable warning : component
185: .getInstallationWarnings()) {
186: properties.add("<html><b>Warning:</b> "
187: + warning.getMessage());
188: }
189: case INSTALLED_SUCCESSFULLY:
190: properties.add("Installation location: "
191: + component.getInstallationLocation());
192: break;
193: case FAILED_TO_INSTALL:
194: properties.add("<html><b>Error:</b> "
195: + component.getInstallationError()
196: .getMessage());
197: break;
198: case UNINSTALLED_WITH_WARNINGS:
199: for (Throwable warning : component
200: .getUninstallationWarnings()) {
201: properties.add("<html><b>Warning:</b> "
202: + warning.getMessage());
203: }
204: case UNINSTALLED_SUCCESSFULLY:
205: break;
206: case FAILED_TO_UNINSTALL:
207: properties.add("<html><b>Error:</b> "
208: + component.getUninstallationError()
209: .getMessage());
210: break;
211: default:
212: break;
213: }
214:
215: propertiesMap.put(component, properties);
216: }
217: }
218:
219: public boolean isLeaf(Object node) {
220: return !((node.equals(root)) || (node instanceof Product));
221: }
222:
223: public void valueForPathChanged(TreePath path, Object newValue) {
224: // do nothing we are read-only
225: }
226:
227: public int getIndexOfChild(Object parent, Object child) {
228: LogManager.log(ErrorLevel.DEBUG, "getIndexOfChild");
229: if (parent.equals(root)) {
230: return components.indexOf(child);
231: } else {
232: String string = (String) child;
233: if (string.startsWith("Installation Location: ")) {
234: return 0;
235: }
236: if (string.startsWith("Disk space:")) {
237: return 1;
238: }
239: return -1;
240: }
241: }
242:
243: public void addTreeModelListener(TreeModelListener listener) {
244: // do nothing we are read-only
245: }
246:
247: public void removeTreeModelListener(TreeModelListener listener) {
248: // do nothing we are read-only
249: }
250: }
251:
252: private static class InstallationDetailsTreeTableModel extends
253: NbiTreeTableModel {
254: public InstallationDetailsTreeTableModel() {
255: super (new InstallationDetailsTreeModel());
256: }
257:
258: public int getTreeColumnIndex() {
259: return 0;
260: }
261:
262: public int getColumnCount() {
263: return 2;
264: }
265:
266: public String getColumnName(int column) {
267: switch (column) {
268: case 0:
269: return ResourceUtils.getString(
270: InstallationDetailsDialog.class,
271: TITLE_COMPONENTS_KEY);
272: case 1:
273: return ResourceUtils.getString(
274: InstallationDetailsDialog.class,
275: TITLE_STATUS_KEY);
276: default:
277: return null;
278: }
279: }
280:
281: public Class<?> getColumnClass(int column) {
282: return Object.class;
283: }
284:
285: public boolean isCellEditable(int row, int column) {
286: return false;
287: }
288:
289: public Object getValueAt(int row, int column) {
290: Object node = getTree().getPathForRow(row)
291: .getLastPathComponent();
292:
293: switch (column) {
294: case 0:
295: return node;
296: case 1:
297: if (node instanceof Product) {
298: return ((Product) node).getDetailedStatus();
299: } else {
300: return null;
301: }
302: default:
303: return null;
304: }
305: }
306:
307: public void setValueAt(Object value, int row, int column) {
308: // do nothing, we're read-only
309: }
310: }
311:
312: public static class InstallationDetailsTreeColumnCellRenderer
313: extends NbiTreeTableColumnCellRenderer {
314: private static final EmptyBorder EMPTY_BORDER = new EmptyBorder(
315: 0, 0, 0, 0);
316: private static final EmptyBorder PADDED_BORDER = new EmptyBorder(
317: 0, 0, 0, 5);
318:
319: public InstallationDetailsTreeColumnCellRenderer(
320: final NbiTreeTable treeTable) {
321: super (treeTable);
322: }
323:
324: public Component getTreeCellRendererComponent(JTree tree,
325: Object value, boolean selected, boolean expanded,
326: boolean leaf, int row, boolean hasFocus) {
327: setOpaque(false);
328: setForeground(treeTable.getForeground());
329: setBackground(treeTable.getBackground());
330:
331: if (value instanceof Product) {
332: Product component = (Product) value;
333:
334: setIcon(component.getIcon());
335: setText(component.getDisplayName());
336:
337: setBorder(EMPTY_BORDER);
338: } else {
339: setIcon(null);
340: setText((value != null) ? value.toString() : "");
341:
342: setBorder(PADDED_BORDER);
343: }
344:
345: return this ;
346: }
347: }
348:
349: public static class InstallationStatusCellRenderer extends JLabel
350: implements TableCellRenderer {
351: public InstallationStatusCellRenderer() {
352: setBorder(new EmptyBorder(0, 5, 0, 5));
353: }
354:
355: public Component getTableCellRendererComponent(JTable table,
356: Object value, boolean isSelected, boolean hasFocus,
357: int row, int column) {
358: setOpaque(false);
359: setBackground(table.getBackground());
360: setForeground(table.getForeground());
361: setText((value instanceof DetailedStatus) ? value
362: .toString() : "");
363:
364: return this;
365: }
366: }
367: }
|