Source Code Cross Referenced for TreePacksPanel.java in  » Installer » IzPack » com » izforge » izpack » panels » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Installer » IzPack » com.izforge.izpack.panels 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
0003:         *
0004:         * http://izpack.org/
0005:         * http://izpack.codehaus.org/
0006:         *
0007:         * Copyright 2007 Vladimir Ralev
0008:         *
0009:         * Licensed under the Apache License, Version 2.0 (the "License");
0010:         * you may not use this file except in compliance with the License.
0011:         * You may obtain a copy of the License at
0012:         *
0013:         *     http://www.apache.org/licenses/LICENSE-2.0
0014:         *
0015:         * Unless required by applicable law or agreed to in writing, software
0016:         * distributed under the License is distributed on an "AS IS" BASIS,
0017:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0018:         * See the License for the specific language governing permissions and
0019:         * limitations under the License.
0020:         */
0021:
0022:        package com.izforge.izpack.panels;
0023:
0024:        import java.awt.Color;
0025:        import java.awt.Component;
0026:        import java.awt.Dimension;
0027:        import java.awt.Graphics;
0028:        import java.awt.GridBagConstraints;
0029:        import java.awt.GridBagLayout;
0030:        import java.awt.event.MouseAdapter;
0031:        import java.awt.event.MouseEvent;
0032:        import java.io.File;
0033:        import java.io.InputStream;
0034:        import java.util.ArrayList;
0035:        import java.util.Enumeration;
0036:        import java.util.HashMap;
0037:        import java.util.Iterator;
0038:        import java.util.List;
0039:        import java.util.Map;
0040:
0041:        import javax.swing.BorderFactory;
0042:        import javax.swing.Box;
0043:        import javax.swing.BoxLayout;
0044:        import javax.swing.Icon;
0045:        import javax.swing.JCheckBox;
0046:        import javax.swing.JLabel;
0047:        import javax.swing.JOptionPane;
0048:        import javax.swing.JPanel;
0049:        import javax.swing.JScrollPane;
0050:        import javax.swing.JTextArea;
0051:        import javax.swing.JTree;
0052:        import javax.swing.UIManager;
0053:        import javax.swing.plaf.metal.MetalLookAndFeel;
0054:        import javax.swing.tree.DefaultMutableTreeNode;
0055:        import javax.swing.tree.TreeCellRenderer;
0056:        import javax.swing.tree.TreeModel;
0057:        import javax.swing.tree.TreeNode;
0058:        import javax.swing.tree.TreePath;
0059:
0060:        import net.n3.nanoxml.XMLElement;
0061:
0062:        import com.izforge.izpack.LocaleDatabase;
0063:        import com.izforge.izpack.Pack;
0064:        import com.izforge.izpack.gui.LabelFactory;
0065:        import com.izforge.izpack.installer.*;
0066:        import com.izforge.izpack.util.Debug;
0067:        import com.izforge.izpack.util.IoHelper;
0068:        import com.izforge.izpack.util.VariableSubstitutor;
0069:
0070:        public class TreePacksPanel extends IzPanel implements 
0071:                PacksPanelInterface {
0072:            /**
0073:             * Required (serializable)
0074:             */
0075:            private static final long serialVersionUID = 5684716698930628262L;
0076:
0077:            // Common used Swing fields
0078:            /**
0079:             * The free space label.
0080:             */
0081:            protected JLabel freeSpaceLabel;
0082:
0083:            /**
0084:             * The space label.
0085:             */
0086:            protected JLabel spaceLabel;
0087:
0088:            /**
0089:             * The tip label.
0090:             */
0091:            protected JTextArea descriptionArea;
0092:
0093:            /**
0094:             * The dependencies label.
0095:             */
0096:            protected JTextArea dependencyArea;
0097:
0098:            /**
0099:             * The packs tree.
0100:             */
0101:            protected JTree packsTree;
0102:
0103:            /**
0104:             * The packs model.
0105:             */
0106:            protected PacksModel packsModel;
0107:
0108:            /**
0109:             * The tablescroll.
0110:             */
0111:            protected JScrollPane tableScroller;
0112:
0113:            // Non-GUI fields
0114:            /**
0115:             * Map that connects names with pack objects
0116:             */
0117:            private Map<String, Pack> names;
0118:
0119:            /**
0120:             * The bytes of the current pack.
0121:             */
0122:            protected long bytes = 0;
0123:
0124:            /**
0125:             * The free bytes of the current selected disk.
0126:             */
0127:            protected long freeBytes = 0;
0128:
0129:            /**
0130:             * Are there dependencies in the packs
0131:             */
0132:            protected boolean dependenciesExist = false;
0133:
0134:            /**
0135:             * The packs locale database.
0136:             */
0137:            private LocaleDatabase langpack = null;
0138:
0139:            /**
0140:             * The name of the XML file that specifies the panel langpack
0141:             */
0142:            private static final String LANG_FILE_NAME = "packsLang.xml";
0143:
0144:            private HashMap<String, Pack> idToPack;
0145:            private HashMap<String, ArrayList<String>> treeData;
0146:            private HashMap<Pack, Integer> packToRowNumber;
0147:
0148:            private HashMap<String, CheckBoxNode> idToCheckBoxNode = new HashMap<String, CheckBoxNode>();
0149:            //private boolean created = false;   // UNUSED
0150:
0151:            private CheckTreeController checkTreeController;
0152:
0153:            /**
0154:             * The constructor.
0155:             * 
0156:             * @param parent The parent window.
0157:             * @param idata The installation data.
0158:             */
0159:            public TreePacksPanel(InstallerFrame parent, InstallData idata) {
0160:                super (parent, idata);
0161:                // Load langpack.
0162:                try {
0163:                    this .langpack = parent.langpack;
0164:                    InputStream langPackStream;
0165:                    String webdir = idata.info.getWebDirURL();
0166:                    if (webdir != null) {
0167:                        try {
0168:                            java.net.URL url = new java.net.URL(webdir
0169:                                    + "/langpacks/" + LANG_FILE_NAME
0170:                                    + idata.localeISO3);
0171:                            langPackStream = new WebAccessor(null)
0172:                                    .openInputStream(url);
0173:                        } catch (Exception e) {
0174:                            langPackStream = ResourceManager.getInstance()
0175:                                    .getInputStream(LANG_FILE_NAME);
0176:                        }
0177:                    } else
0178:                        langPackStream = ResourceManager.getInstance()
0179:                                .getInputStream(LANG_FILE_NAME);
0180:
0181:                    this .langpack.add(langPackStream);
0182:                    langPackStream.close();
0183:                } catch (Throwable exception) {
0184:                    Debug.trace(exception);
0185:                }
0186:
0187:                // init the map
0188:                computePacks(idata.availablePacks);
0189:
0190:            }
0191:
0192:            /**
0193:             * The Implementation of this method should create the layout for the current class.
0194:             */
0195:
0196:            protected void createNormalLayout() {
0197:                this .removeAll();
0198:                setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
0199:                createLabel("PacksPanel.info", "preferences", null, null);
0200:                add(Box.createRigidArea(new Dimension(0, 3)));
0201:                createLabel("PacksPanel.tip", "tip", null, null);
0202:                add(Box.createRigidArea(new Dimension(0, 5)));
0203:                tableScroller = new JScrollPane();
0204:                packsTree = createPacksTree(300, tableScroller, null, null);
0205:                if (dependenciesExist)
0206:                    dependencyArea = createTextArea(
0207:                            "PacksPanel.dependencyList", null, null, null);
0208:                descriptionArea = createTextArea("PacksPanel.description",
0209:                        null, null, null);
0210:                spaceLabel = createPanelWithLabel("PacksPanel.space", null,
0211:                        null);
0212:                if (IoHelper.supported("getFreeSpace")) {
0213:                    add(Box.createRigidArea(new Dimension(0, 3)));
0214:                    freeSpaceLabel = createPanelWithLabel(
0215:                            "PacksPanel.freespace", null, null);
0216:                }
0217:            }
0218:
0219:            /*
0220:             * (non-Javadoc)
0221:             * 
0222:             * @see com.izforge.izpack.panels.PacksPanelInterface#getLangpack()
0223:             */
0224:            public LocaleDatabase getLangpack() {
0225:                return (langpack);
0226:            }
0227:
0228:            /*
0229:             * (non-Javadoc)
0230:             * 
0231:             * @see com.izforge.izpack.panels.PacksPanelInterface#getBytes()
0232:             */
0233:            public long getBytes() {
0234:                return (bytes);
0235:            }
0236:
0237:            /*
0238:             * (non-Javadoc)
0239:             * 
0240:             * @see com.izforge.izpack.panels.PacksPanelInterface#setBytes(int)
0241:             */
0242:            public void setBytes(long bytes) {
0243:                this .bytes = bytes;
0244:            }
0245:
0246:            /*
0247:             * (non-Javadoc)
0248:             * 
0249:             * @see com.izforge.izpack.panels.PacksPanelInterface#showSpaceRequired()
0250:             */
0251:            public void showSpaceRequired() {
0252:                if (spaceLabel != null)
0253:                    spaceLabel.setText(Pack.toByteUnitsString(bytes));
0254:            }
0255:
0256:            /*
0257:             * (non-Javadoc)
0258:             * 
0259:             * @see com.izforge.izpack.panels.PacksPanelInterface#showFreeSpace()
0260:             */
0261:            public void showFreeSpace() {
0262:                if (IoHelper.supported("getFreeSpace")
0263:                        && freeSpaceLabel != null) {
0264:                    String msg = null;
0265:                    freeBytes = IoHelper
0266:                            .getFreeSpace(IoHelper.existingParent(
0267:                                    new File(idata.getInstallPath()))
0268:                                    .getAbsolutePath());
0269:                    if (freeBytes < 0)
0270:                        msg = parent.langpack
0271:                                .getString("PacksPanel.notAscertainable");
0272:                    else
0273:                        msg = Pack.toByteUnitsString(freeBytes);
0274:                    freeSpaceLabel.setText(msg);
0275:                }
0276:            }
0277:
0278:            public Debugger getDebugger() {
0279:                return null;
0280:            }
0281:
0282:            /**
0283:             * Indicates wether the panel has been validated or not.
0284:             * 
0285:             * @return true if the needed space is less than the free space, else false
0286:             */
0287:            public boolean isValidated() {
0288:                refreshPacksToInstall();
0289:                if (IoHelper.supported("getFreeSpace") && freeBytes >= 0
0290:                        && freeBytes <= bytes) {
0291:                    JOptionPane.showMessageDialog(this , parent.langpack
0292:                            .getString("PacksPanel.notEnoughSpace"),
0293:                            parent.langpack.getString("installer.error"),
0294:                            JOptionPane.ERROR_MESSAGE);
0295:                    return (false);
0296:                }
0297:                return (true);
0298:            }
0299:
0300:            /**
0301:             * Asks to make the XML panel data.
0302:             * 
0303:             * @param panelRoot The XML tree to write the data in.
0304:             */
0305:            public void makeXMLData(XMLElement panelRoot) {
0306:                new ImgPacksPanelAutomationHelper().makeXMLData(idata,
0307:                        panelRoot);
0308:            }
0309:
0310:            /**
0311:             * This method tries to resolve the localized name of the given pack. If this is not possible,
0312:             * the name given in the installation description file in ELEMENT <pack> will be used.
0313:             * 
0314:             * @param pack for which the name should be resolved
0315:             * @return localized name of the pack
0316:             */
0317:            private String getI18NPackName(Pack pack) {
0318:                // Internationalization code
0319:                String packName = pack.name;
0320:                String key = pack.id;
0321:                if (langpack != null && pack.id != null && !"".equals(pack.id)) {
0322:                    packName = langpack.getString(key);
0323:                }
0324:                if ("".equals(packName) || key == null || key.equals(packName)) {
0325:                    packName = pack.name;
0326:                }
0327:                return (packName);
0328:            }
0329:
0330:            public String getI18NPackName(String packId) {
0331:                Pack pack = idToPack.get(packId);
0332:                if (pack == null)
0333:                    return packId;
0334:                // Internationalization code
0335:                String packName = pack.name;
0336:                String key = pack.id;
0337:                if (langpack != null && pack.id != null && !"".equals(pack.id)) {
0338:                    packName = langpack.getString(key);
0339:                }
0340:                if ("".equals(packName) || key == null || key.equals(packName)) {
0341:                    packName = pack.name;
0342:                }
0343:                return (packName);
0344:            }
0345:
0346:            /**
0347:             * Layout helper method:<br>
0348:             * Creates an label with a message given by msgId and an icon given by the iconId. If layout and
0349:             * constraints are not null, the label will be added to layout with the given constraints. The
0350:             * label will be added to this object.
0351:             * 
0352:             * @param msgId identifier for the IzPack langpack
0353:             * @param iconId identifier for the IzPack icons
0354:             * @param layout layout to be used
0355:             * @param constraints constraints to be used
0356:             * @return the created label
0357:             */
0358:            protected JLabel createLabel(String msgId, String iconId,
0359:                    GridBagLayout layout, GridBagConstraints constraints) {
0360:                JLabel label = LabelFactory.create(parent.langpack
0361:                        .getString(msgId), parent.icons.getImageIcon(iconId),
0362:                        TRAILING);
0363:                if (layout != null && constraints != null)
0364:                    layout.addLayoutComponent(label, constraints);
0365:                add(label);
0366:                return (label);
0367:            }
0368:
0369:            /**
0370:             * Creates a panel containing a anonymous label on the left with the message for the given msgId
0371:             * and a label on the right side with initial no text. The right label will be returned. If
0372:             * layout and constraints are not null, the label will be added to layout with the given
0373:             * constraints. The panel will be added to this object.
0374:             * 
0375:             * @param msgId identifier for the IzPack langpack
0376:             * @param layout layout to be used
0377:             * @param constraints constraints to be used
0378:             * @return the created (right) label
0379:             */
0380:            protected JLabel createPanelWithLabel(String msgId,
0381:                    GridBagLayout layout, GridBagConstraints constraints) {
0382:                JPanel panel = new JPanel();
0383:                JLabel label = new JLabel();
0384:                if (label == null)
0385:                    label = new JLabel("");
0386:                panel.setAlignmentX(LEFT_ALIGNMENT);
0387:                panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
0388:                panel
0389:                        .add(LabelFactory.create(parent.langpack
0390:                                .getString(msgId)));
0391:                panel.add(Box.createHorizontalGlue());
0392:                panel.add(label);
0393:                if (layout != null && constraints != null)
0394:                    layout.addLayoutComponent(panel, constraints);
0395:                add(panel);
0396:                return (label);
0397:            }
0398:
0399:            private void refreshPacksToInstall() {
0400:                idata.selectedPacks.clear();
0401:                CheckBoxNode cbn = (CheckBoxNode) getTree().getModel()
0402:                        .getRoot();
0403:                Enumeration e = cbn.depthFirstEnumeration();
0404:                while (e.hasMoreElements()) {
0405:                    CheckBoxNode c = (CheckBoxNode) e.nextElement();
0406:                    if (c.isSelected() || c.isPartial()) {
0407:                        idata.selectedPacks.add(c.getPack());
0408:                    }
0409:                }
0410:            }
0411:
0412:            /**
0413:             * Creates a text area with standard settings and the title given by the msgId. If scroller is
0414:             * not null, the create text area will be added to the scroller and the scroller to this object,
0415:             * else the text area will be added directly to this object. If layout and constraints are not
0416:             * null, the text area or scroller will be added to layout with the given constraints. The text
0417:             * area will be returned.
0418:             * 
0419:             * @param msgId identifier for the IzPack langpack
0420:             * @param scroller the scroller to be used
0421:             * @param layout layout to be used
0422:             * @param constraints constraints to be used
0423:             * @return the created text area
0424:             */
0425:            protected JTextArea createTextArea(String msgId,
0426:                    JScrollPane scroller, GridBagLayout layout,
0427:                    GridBagConstraints constraints) {
0428:                JTextArea area = new JTextArea();
0429:                // area.setMargin(new Insets(2, 2, 2, 2));
0430:                area.setAlignmentX(LEFT_ALIGNMENT);
0431:                area.setCaretPosition(0);
0432:                area.setEditable(false);
0433:                area.setEditable(false);
0434:                area.setOpaque(false);
0435:                area.setLineWrap(true);
0436:                area.setWrapStyleWord(true);
0437:                area.setBorder(BorderFactory.createTitledBorder(parent.langpack
0438:                        .getString(msgId)));
0439:                area.setFont(getControlTextFont());
0440:
0441:                if (layout != null && constraints != null) {
0442:                    if (scroller != null) {
0443:                        layout.addLayoutComponent(scroller, constraints);
0444:                    } else
0445:                        layout.addLayoutComponent(area, constraints);
0446:                }
0447:                if (scroller != null) {
0448:                    scroller.setViewportView(area);
0449:                    add(scroller);
0450:                } else
0451:                    add(area);
0452:                return (area);
0453:
0454:            }
0455:
0456:            /**
0457:             * FIXME Creates the JTree component and calls all initialization tasks
0458:             * 
0459:             * @param width
0460:             * @param scroller
0461:             * @param layout
0462:             * @param constraints
0463:             * @return
0464:             */
0465:            protected JTree createPacksTree(int width, JScrollPane scroller,
0466:                    GridBagLayout layout, GridBagConstraints constraints) {
0467:                JTree tree = new JTree((CheckBoxNode) populateTreePacks(null));
0468:                packsTree = tree;
0469:                tree.setCellRenderer(new CheckBoxNodeRenderer(this ));
0470:                tree.setEditable(false);
0471:                tree.setShowsRootHandles(true);
0472:                tree.setRootVisible(false);
0473:                checkTreeController = new CheckTreeController(this );
0474:                tree.addMouseListener(checkTreeController);
0475:                tree.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
0476:                tree.setBackground(Color.white);
0477:                tree.setToggleClickCount(0);
0478:                //tree.setRowHeight(0);
0479:
0480:                //table.getSelectionModel().addTreeSelectionListener(this);
0481:                scroller.setViewportView(tree);
0482:                scroller.setAlignmentX(LEFT_ALIGNMENT);
0483:                scroller.getViewport().setBackground(Color.white);
0484:                scroller.setPreferredSize(new Dimension(width,
0485:                        (idata.guiPrefs.height / 3 + 30)));
0486:
0487:                if (layout != null && constraints != null)
0488:                    layout.addLayoutComponent(scroller, constraints);
0489:                add(scroller);
0490:                return (tree);
0491:            }
0492:
0493:            /**
0494:             * Computes pack related data like the names or the dependencies state.
0495:             * 
0496:             * @param packs
0497:             */
0498:            private void computePacks(List packs) {
0499:                names = new HashMap<String, Pack>();
0500:                dependenciesExist = false;
0501:                for (Object pack1 : packs) {
0502:                    Pack pack = (Pack) pack1;
0503:                    names.put(pack.name, pack);
0504:                    if (pack.dependencies != null || pack.excludeGroup != null) {
0505:                        dependenciesExist = true;
0506:                    }
0507:                }
0508:            }
0509:
0510:            /**
0511:             * Refresh tree data from the PacksModel. This functions serves as a bridge
0512:             * between the flat PacksModel and the tree data model. 
0513:             *
0514:             */
0515:            public void fromModel() {
0516:                TreeModel model = this .packsTree.getModel();
0517:                CheckBoxNode root = (CheckBoxNode) model.getRoot();
0518:                updateModel(root);
0519:            }
0520:
0521:            private int getRowIndex(Pack pack) {
0522:                Object o = packToRowNumber.get(pack);
0523:                if (o == null)
0524:                    return -1;
0525:                Integer ret = (Integer) o;
0526:                return ret;
0527:            }
0528:
0529:            /**
0530:             * Helper function for fromModel() - runs the recursion
0531:             * 
0532:             * @param rnode
0533:             */
0534:            private void updateModel(CheckBoxNode rnode) {
0535:                int rowIndex = getRowIndex(rnode.getPack());
0536:                if (rowIndex > 0) {
0537:                    Integer state = (Integer) packsModel
0538:                            .getValueAt(rowIndex, 0);
0539:                    if ((state == -2) && rnode.getChildCount() > 0) {
0540:                        boolean dirty = false;
0541:                        Enumeration toBeDeselected = rnode
0542:                                .depthFirstEnumeration();
0543:                        while (toBeDeselected.hasMoreElements()) {
0544:                            CheckBoxNode cbn = (CheckBoxNode) toBeDeselected
0545:                                    .nextElement();
0546:                            boolean chDirty = cbn.isSelected()
0547:                                    || cbn.isPartial() || cbn.isEnabled();
0548:                            dirty = dirty || chDirty;
0549:                            if (chDirty) {
0550:                                cbn.setPartial(false);
0551:                                cbn.setSelected(false);
0552:                                cbn.setEnabled(false);
0553:                                setModelValue(cbn);
0554:                            }
0555:                        }
0556:                        if (dirty)
0557:                            fromModel();
0558:                        return;
0559:                    }
0560:                }
0561:
0562:                Enumeration e = rnode.children();
0563:                while (e.hasMoreElements()) {
0564:                    Object next = e.nextElement();
0565:                    CheckBoxNode cbnode = (CheckBoxNode) next;
0566:                    String nodeText = cbnode.getId();
0567:                    Object nodePack = idToPack.get(nodeText);
0568:                    if (!cbnode.isPartial()) {
0569:                        int childRowIndex = getRowIndex((Pack) nodePack);
0570:                        if (childRowIndex > 0) {
0571:                            Integer state = (Integer) packsModel.getValueAt(
0572:                                    childRowIndex, 0);
0573:                            cbnode.setEnabled(state >= 0);
0574:                            cbnode.setSelected(Math.abs(state.intValue()) == 1);
0575:                        }
0576:                    }
0577:                    updateModel(cbnode);
0578:                }
0579:            }
0580:
0581:            /**
0582:             * Updates a value for pack in PacksModel with data from a checkbox node
0583:             * 
0584:             * @param cbnode This is the checkbox node which contains model values
0585:             */
0586:            public void setModelValue(CheckBoxNode cbnode) {
0587:                String id = cbnode.getId();
0588:                Object nodePack = idToPack.get(id);
0589:                int value = 0;
0590:                if (cbnode.isEnabled() && cbnode.isSelected())
0591:                    value = 1;
0592:                if (!cbnode.isEnabled() && cbnode.isSelected())
0593:                    value = -1;
0594:                if (!cbnode.isEnabled() && !cbnode.isSelected())
0595:                    value = -2;
0596:                int rowIndex = getRowIndex((Pack) nodePack);
0597:                if (rowIndex > 0) {
0598:                    Integer newValue = value;
0599:                    Integer modelValue = (Integer) packsModel.getValueAt(
0600:                            rowIndex, 0);
0601:                    if (!newValue.equals(modelValue))
0602:                        packsModel.setValueAt(newValue, rowIndex, 0);
0603:                }
0604:            }
0605:
0606:            /**
0607:             * Initialize tree model sructures
0608:             *
0609:             */
0610:            private void createTreeData() {
0611:                treeData = new HashMap<String, ArrayList<String>>();
0612:                idToPack = new HashMap<String, Pack>();
0613:
0614:                java.util.Iterator iter = idata.availablePacks.iterator();
0615:                while (iter.hasNext()) {
0616:                    Pack p = (Pack) iter.next();
0617:                    idToPack.put(p.id, p);
0618:                    if (p.parent != null) {
0619:                        ArrayList<String> kids = null;
0620:                        if (treeData.containsKey(p.parent))
0621:                            kids = treeData.get(p.parent);
0622:                        else {
0623:                            kids = new ArrayList<String>();
0624:                        }
0625:                        kids.add(p.id);
0626:                        treeData.put(p.parent, kids);
0627:                    }
0628:                }
0629:            }
0630:
0631:            /**
0632:             * Shows and updates the description text in the panel
0633:             * 
0634:             * @param id
0635:             */
0636:            public void setDescription(String id) {
0637:                VariableSubstitutor vs = new VariableSubstitutor(idata
0638:                        .getVariables());
0639:                if (descriptionArea != null) {
0640:                    Pack pack = idToPack.get(id);
0641:                    String desc = "";
0642:                    String key = pack.id + ".description";
0643:                    if (langpack != null && pack.id != null
0644:                            && !"".equals(pack.id)) {
0645:                        desc = langpack.getString(key);
0646:                    }
0647:                    if ("".equals(desc) || key.equals(desc)) {
0648:                        desc = pack.description;
0649:                    }
0650:                    desc = vs.substitute(desc, null);
0651:                    descriptionArea.setText(desc);
0652:                }
0653:            }
0654:
0655:            /**
0656:             * Shows and updates the dependencies text in the panel
0657:             * 
0658:             * @param id
0659:             */
0660:            public void setDependencies(String id) {
0661:                if (dependencyArea != null) {
0662:                    Pack pack = idToPack.get(id);
0663:                    List<String> dep = pack.dependencies;
0664:                    String list = "";
0665:                    if (dep != null) {
0666:                        list += (langpack == null) ? "Dependencies: "
0667:                                : langpack.getString("PacksPanel.dependencies");
0668:                    }
0669:                    for (int j = 0; dep != null && j < dep.size(); j++) {
0670:                        String name = dep.get(j);
0671:                        list += getI18NPackName(names.get(name));
0672:                        if (j != dep.size() - 1)
0673:                            list += ", ";
0674:                    }
0675:
0676:                    // add the list of the packs to be excluded
0677:                    String excludeslist = (langpack == null) ? "Excludes: "
0678:                            : langpack.getString("PacksPanel.excludes");
0679:                    int numexcludes = 0;
0680:                    int i = getRowIndex(pack);
0681:                    if (pack.excludeGroup != null) {
0682:                        for (int q = 0; q < idata.availablePacks.size(); q++) {
0683:                            Pack otherpack = (Pack) idata.availablePacks.get(q);
0684:                            String exgroup = otherpack.excludeGroup;
0685:                            if (exgroup != null) {
0686:                                if (q != i && pack.excludeGroup.equals(exgroup)) {
0687:
0688:                                    excludeslist += getI18NPackName(otherpack)
0689:                                            + ", ";
0690:                                    numexcludes++;
0691:                                }
0692:                            }
0693:                        }
0694:                    }
0695:                    // concatenate
0696:                    if (dep != null)
0697:                        excludeslist = "    " + excludeslist;
0698:                    if (numexcludes > 0)
0699:                        list += excludeslist;
0700:                    if (list.endsWith(", "))
0701:                        list = list.substring(0, list.length() - 2);
0702:
0703:                    // and display the result
0704:                    dependencyArea.setText(list);
0705:                }
0706:            }
0707:
0708:            /**
0709:             * Gives a CheckBoxNode instance from the id
0710:             * 
0711:             * @param id
0712:             * @return
0713:             */
0714:            public CheckBoxNode getCbnById(String id) {
0715:                return this .idToCheckBoxNode.get(id);
0716:            }
0717:
0718:            /**
0719:             * Reads the available packs and creates the JTree structure based on
0720:             * the parent definitions.
0721:             * 
0722:             * @param parent
0723:             * @return
0724:             */
0725:            private Object populateTreePacks(String parent) {
0726:                if (parent == null) // the root node
0727:                {
0728:                    java.util.Iterator iter = idata.availablePacks.iterator();
0729:                    ArrayList rootNodes = new ArrayList();
0730:                    while (iter.hasNext()) {
0731:                        Pack p = (Pack) iter.next();
0732:                        if (p.parent == null) {
0733:                            rootNodes.add(populateTreePacks(p.id));
0734:                        }
0735:                    }
0736:                    TreeNode nv = new CheckBoxNode("Root", "Root", rootNodes
0737:                            .toArray(), true);
0738:                    return nv;
0739:                } else {
0740:                    ArrayList links = new ArrayList();
0741:                    Object kidsObject = treeData.get(parent);
0742:                    Pack p = idToPack.get(parent);
0743:                    String translated = getI18NPackName(parent);
0744:
0745:                    if (kidsObject != null) {
0746:                        ArrayList kids = (ArrayList) kidsObject;
0747:                        for (Object kid : kids) {
0748:                            String kidId = (String) kid;
0749:                            links.add(populateTreePacks(kidId));
0750:                        }
0751:
0752:                        CheckBoxNode cbn = new CheckBoxNode(parent, translated,
0753:                                links.toArray(), true);
0754:                        idToCheckBoxNode.put(cbn.getId(), cbn);
0755:                        cbn.setPack(p);
0756:                        cbn.setTotalSize(p.nbytes);
0757:                        return cbn;
0758:                    } else {
0759:                        CheckBoxNode cbn = new CheckBoxNode(parent, translated,
0760:                                true);
0761:                        idToCheckBoxNode.put(cbn.getId(), cbn);
0762:                        cbn.setPack(p);
0763:                        cbn.setTotalSize(p.nbytes);
0764:                        return cbn;
0765:                    }
0766:                }
0767:            }
0768:
0769:            /**
0770:             * Called when the panel becomes active. If a derived class implements this method also, it is
0771:             * recomanded to call this method with the super operator first.
0772:             */
0773:            public void panelActivate() {
0774:                try {
0775:
0776:                    // TODO the PacksModel could be patched such that isCellEditable
0777:                    // allows returns false. In that case the PacksModel must not be
0778:                    // adapted here.
0779:                    packsModel = new PacksModel(this , idata, this .parent
0780:                            .getRules()) {
0781:                        /**
0782:                         * Required (serializable)
0783:                         */
0784:                        private static final long serialVersionUID = 697462278279845304L;
0785:
0786:                        public boolean isCellEditable(int rowIndex,
0787:                                int columnIndex) {
0788:                            return false;
0789:                        }
0790:                    };
0791:
0792:                    //initialize helper map to increa performance
0793:                    packToRowNumber = new HashMap<Pack, Integer>();
0794:                    java.util.Iterator rowpack = idata.availablePacks
0795:                            .iterator();
0796:                    while (rowpack.hasNext()) {
0797:                        Pack p = (Pack) rowpack.next();
0798:                        packToRowNumber.put(p, idata.availablePacks.indexOf(p));
0799:                    }
0800:
0801:                    // Init tree structures
0802:                    createTreeData();
0803:
0804:                    // Create panel GUI (and populate the TJtree)
0805:                    createNormalLayout();
0806:
0807:                    // Reload the data from the PacksModel into the tree in order the initial
0808:                    // dependencies to be resolved and effective
0809:                    fromModel();
0810:
0811:                    // Init the pack sizes (individual and cumulative)
0812:                    CheckBoxNode root = (CheckBoxNode) packsTree.getModel()
0813:                            .getRoot();
0814:                    checkTreeController.updateAllParents(root);
0815:                    CheckTreeController.initTotalSize(root, false);
0816:
0817:                    // Ugly repaint because of a bug in tree.treeDidChange
0818:                    packsTree.revalidate();
0819:                    packsTree.repaint();
0820:
0821:                    tableScroller.setColumnHeaderView(null);
0822:                    tableScroller.setColumnHeader(null);
0823:
0824:                    // set the JCheckBoxes to the currently selected panels. The
0825:                    // selection might have changed in another panel
0826:                    java.util.Iterator iter = idata.availablePacks.iterator();
0827:                    bytes = 0;
0828:                    while (iter.hasNext()) {
0829:                        Pack p = (Pack) iter.next();
0830:                        if (p.required) {
0831:                            bytes += p.nbytes;
0832:                            continue;
0833:                        }
0834:                        if (idata.selectedPacks.contains(p))
0835:                            bytes += p.nbytes;
0836:                    }
0837:                } catch (Exception e) {
0838:                    e.printStackTrace();
0839:                }
0840:                showSpaceRequired();
0841:                showFreeSpace();
0842:            }
0843:
0844:            /*
0845:             * (non-Javadoc)
0846:             * 
0847:             * @see com.izforge.izpack.installer.IzPanel#getSummaryBody()
0848:             */
0849:            public String getSummaryBody() {
0850:                StringBuffer retval = new StringBuffer(256);
0851:                Iterator iter = idata.selectedPacks.iterator();
0852:                boolean first = true;
0853:                while (iter.hasNext()) {
0854:                    if (!first) {
0855:                        retval.append("<br>");
0856:                    }
0857:                    first = false;
0858:                    Pack pack = (Pack) iter.next();
0859:                    if (langpack != null && pack.id != null
0860:                            && !"".equals(pack.id)) {
0861:                        retval.append(langpack.getString(pack.id));
0862:                    } else
0863:                        retval.append(pack.name);
0864:                }
0865:                return (retval.toString());
0866:            }
0867:
0868:            public JTree getTree() {
0869:                return packsTree;
0870:            }
0871:
0872:        }
0873:
0874:        /**
0875:         * 
0876:         * The renderer model for individual checkbox nodes in a JTree. It renders the
0877:         * checkbox and a label for the pack size.
0878:         * 
0879:         * @author <a href="vralev@redhat.com">Vladimir Ralev</a>
0880:         * @version $Revision: 1.1 $
0881:         */
0882:        class CheckBoxNodeRenderer implements  TreeCellRenderer {
0883:            private static final JPanel rendererPanel = new JPanel();
0884:            private static final JLabel packSizeLabel = new JLabel();
0885:            private static final JCheckBox checkbox = new JCheckBox();
0886:            private static final JCheckBox normalCheckBox = new JCheckBox();
0887:            private static final java.awt.Font normalFont = new JCheckBox()
0888:                    .getFont();
0889:            private static final java.awt.Font boldFont = new java.awt.Font(
0890:                    normalFont.getFontName(), java.awt.Font.BOLD, normalFont
0891:                            .getSize());
0892:            private static final java.awt.Font plainFont = new java.awt.Font(
0893:                    normalFont.getFontName(), java.awt.Font.PLAIN, normalFont
0894:                            .getSize());
0895:            private static final Color annotationColor = new Color(0, 0, 120); // red
0896:            private static final Color changedColor = new Color(200, 0, 0);
0897:
0898:            private static Color selectionForeground, selectionBackground,
0899:                    textForeground, textBackground;
0900:
0901:            TreePacksPanel treePacksPanel;
0902:
0903:            public CheckBoxNodeRenderer(TreePacksPanel t) {
0904:                selectionForeground = UIManager
0905:                        .getColor("Tree.selectionForeground");
0906:                selectionBackground = UIManager
0907:                        .getColor("Tree.selectionBackground");
0908:                textForeground = UIManager.getColor("Tree.textForeground");
0909:                textBackground = UIManager.getColor("Tree.textBackground");
0910:                treePacksPanel = t;
0911:
0912:                int treeWidth = t.getTree().getPreferredSize().width;
0913:                int height = checkbox.getPreferredSize().height;
0914:                int cellWidth = treeWidth - treeWidth / 4;
0915:
0916:                //Don't touch, it fixes various layout bugs in swing/awt
0917:                rendererPanel.setLayout(new java.awt.BorderLayout(0, 0));
0918:                rendererPanel.setBackground(textBackground);
0919:                rendererPanel.add(java.awt.BorderLayout.WEST, checkbox);
0920:
0921:                rendererPanel.setAlignmentX((float) 0);
0922:                rendererPanel.setAlignmentY((float) 0);
0923:                rendererPanel.add(java.awt.BorderLayout.EAST, packSizeLabel);
0924:
0925:                rendererPanel.setMinimumSize(new Dimension(cellWidth, height));
0926:                rendererPanel
0927:                        .setPreferredSize(new Dimension(cellWidth, height));
0928:                rendererPanel.setSize(new Dimension(cellWidth, height));
0929:
0930:                rendererPanel.setBorder(BorderFactory.createEmptyBorder(0, 0,
0931:                        0, 0));
0932:            }
0933:
0934:            public Component getTreeCellRendererComponent(JTree tree,
0935:                    Object value, boolean selected, boolean expanded,
0936:                    boolean leaf, int row, boolean hasFocus) {
0937:                treePacksPanel.fromModel();
0938:
0939:                if (selected) {
0940:                    checkbox.setForeground(selectionForeground);
0941:                    checkbox.setBackground(selectionBackground);
0942:                    rendererPanel.setForeground(selectionForeground);
0943:                    rendererPanel.setBackground(selectionBackground);
0944:                    packSizeLabel.setBackground(selectionBackground);
0945:                } else {
0946:                    checkbox.setForeground(textForeground);
0947:                    checkbox.setBackground(textBackground);
0948:                    rendererPanel.setForeground(textForeground);
0949:                    rendererPanel.setBackground(textBackground);
0950:                    packSizeLabel.setBackground(textBackground);
0951:                }
0952:
0953:                if ((value != null) && (value instanceof  CheckBoxNode)) {
0954:                    CheckBoxNode node = (CheckBoxNode) value;
0955:
0956:                    if (node.isTotalSizeChanged())
0957:                        packSizeLabel.setForeground(changedColor);
0958:                    else {
0959:                        if (selected)
0960:                            packSizeLabel.setForeground(selectionForeground);
0961:                        else {
0962:                            packSizeLabel.setForeground(annotationColor);
0963:                        }
0964:                    }
0965:
0966:                    checkbox.setText(node.getTranslatedText());
0967:
0968:                    packSizeLabel.setText(Pack.toByteUnitsString(node
0969:                            .getTotalSize()));
0970:
0971:                    if (node.isPartial())
0972:                        checkbox.setSelected(false);
0973:                    else
0974:                        checkbox.setSelected(node.isSelected());
0975:
0976:                    checkbox.setEnabled(node.isEnabled());
0977:                    packSizeLabel.setEnabled(node.isEnabled());
0978:
0979:                    if (node.getChildCount() > 0) {
0980:                        checkbox.setFont(boldFont);
0981:                        packSizeLabel.setFont(boldFont);
0982:                    } else {
0983:                        checkbox.setFont(normalFont);
0984:                        packSizeLabel.setFont(plainFont);
0985:                    }
0986:
0987:                    if (node.isPartial()) {
0988:                        checkbox.setIcon(new PartialIcon());
0989:                    } else {
0990:                        checkbox.setIcon(normalCheckBox.getIcon());
0991:                    }
0992:                }
0993:                return rendererPanel;
0994:            }
0995:
0996:            public Component getCheckRenderer() {
0997:                return rendererPanel;
0998:            }
0999:
1000:        }
1001:
1002:        /**
1003:         * 
1004:         * The model structure for a JTree node.
1005:         * 
1006:         * @author <a href="vralev@redhat.com">Vladimir Ralev</a>
1007:         * @version $Revision: 1.1 $
1008:         */
1009:        class CheckBoxNode extends DefaultMutableTreeNode {
1010:
1011:            /**
1012:             * Required (serializable)
1013:             */
1014:            private static final long serialVersionUID = 8743154051564336973L;
1015:            String id;
1016:            boolean selected;
1017:            boolean partial;
1018:            boolean enabled;
1019:            boolean totalSizeChanged;
1020:            String translatedText;
1021:            Pack pack;
1022:            long totalSize;
1023:
1024:            public CheckBoxNode(String id, String translated, boolean selected) {
1025:                this .id = id;
1026:                this .selected = selected;
1027:                this .translatedText = translated;
1028:            }
1029:
1030:            public CheckBoxNode(String id, String translated,
1031:                    Object elements[], boolean selected) {
1032:                this .id = id;
1033:                this .translatedText = translated;
1034:                for (int i = 0, n = elements.length; i < n; i++) {
1035:                    CheckBoxNode tn = (CheckBoxNode) elements[i];
1036:                    add(tn);
1037:                }
1038:            }
1039:
1040:            public boolean isLeaf() {
1041:                return this .getChildCount() == 0;
1042:            }
1043:
1044:            public boolean isSelected() {
1045:                return selected;
1046:            }
1047:
1048:            public void setSelected(boolean newValue) {
1049:                selected = newValue;
1050:            }
1051:
1052:            public String getId() {
1053:                return id;
1054:            }
1055:
1056:            public void setId(String newValue) {
1057:                id = newValue;
1058:            }
1059:
1060:            public String toString() {
1061:                return getClass().getName() + "[" + id + "/" + selected + "]";
1062:            }
1063:
1064:            public boolean isPartial() {
1065:                return partial;
1066:            }
1067:
1068:            public void setPartial(boolean partial) {
1069:                this .partial = partial;
1070:                if (partial)
1071:                    setSelected(true);
1072:            }
1073:
1074:            public boolean isEnabled() {
1075:                return enabled;
1076:            }
1077:
1078:            public void setEnabled(boolean enabled) {
1079:                this .enabled = enabled;
1080:            }
1081:
1082:            public String getTranslatedText() {
1083:                return translatedText;
1084:            }
1085:
1086:            public void setTranslatedText(String translatedText) {
1087:                this .translatedText = translatedText;
1088:            }
1089:
1090:            public Pack getPack() {
1091:                return pack;
1092:            }
1093:
1094:            public void setPack(Pack pack) {
1095:                this .pack = pack;
1096:            }
1097:
1098:            public long getTotalSize() {
1099:                return totalSize;
1100:            }
1101:
1102:            public void setTotalSize(long totalSize) {
1103:                this .totalSize = totalSize;
1104:            }
1105:
1106:            public boolean isTotalSizeChanged() {
1107:                return totalSizeChanged;
1108:            }
1109:
1110:            public void setTotalSizeChanged(boolean totalSizeChanged) {
1111:                this .totalSizeChanged = totalSizeChanged;
1112:            }
1113:        }
1114:
1115:        /**
1116:         * 
1117:         * Special checkbox icon which shows partially selected nodes.
1118:         * 
1119:         * @author <a href="vralev@redhat.com">Vladimir Ralev</a>
1120:         * @version $Revision: 1.1 $
1121:         */
1122:        class PartialIcon implements  Icon {
1123:            protected int getControlSize() {
1124:                return 13;
1125:            }
1126:
1127:            public void paintIcon(Component c, Graphics g, int x, int y) {
1128:                int controlSize = getControlSize();
1129:                g.setColor(MetalLookAndFeel.getControlShadow());
1130:                g.fillRect(x, y, controlSize - 1, controlSize - 1);
1131:                drawBorder(g, x, y, controlSize, controlSize);
1132:
1133:                g.setColor(Color.green);
1134:                drawCheck(c, g, x, y);
1135:            }
1136:
1137:            private void drawBorder(Graphics g, int x, int y, int w, int h) {
1138:                g.translate(x, y);
1139:
1140:                // outer frame rectangle
1141:                g.setColor(MetalLookAndFeel.getControlDarkShadow());
1142:                g.setColor(new Color(0.4f, 0.4f, 0.4f));
1143:                g.drawRect(0, 0, w - 2, h - 2);
1144:
1145:                // middle frame
1146:                g.setColor(MetalLookAndFeel.getControlHighlight());
1147:                g.setColor(new Color(0.6f, 0.6f, 0.6f));
1148:                g.drawRect(1, 1, w - 2, h - 2);
1149:
1150:                // background
1151:                g.setColor(new Color(0.99f, 0.99f, 0.99f));
1152:                g.fillRect(2, 2, w - 3, h - 3);
1153:
1154:                //some extra lines for FX
1155:                g.setColor(MetalLookAndFeel.getControl());
1156:                g.drawLine(0, h - 1, 1, h - 2);
1157:                g.drawLine(w - 1, 0, w - 2, 1);
1158:                g.translate(-x, -y);
1159:            }
1160:
1161:            protected void drawCheck(Component c, Graphics g, int x, int y) {
1162:                int controlSize = getControlSize();
1163:                g.setColor(new Color(0.0f, 0.7f, 0.0f));
1164:
1165:                g.fillOval(x + controlSize / 2 - 2, y + controlSize / 2 - 2, 6,
1166:                        6);
1167:            }
1168:
1169:            public int getIconWidth() {
1170:                return getControlSize();
1171:            }
1172:
1173:            public int getIconHeight() {
1174:                return getControlSize();
1175:            }
1176:        }
1177:
1178:        /**
1179:         * 
1180:         * Controller class which handles the mouse clicks on checkbox nodes. Also
1181:         * contains utility methods to update the sizes and the states of the nodes.
1182:         * 
1183:         * @author <a href="vralev@redhat.com">Vladimir Ralev</a>
1184:         * @version $Revision: 1.1 $
1185:         */
1186:        class CheckTreeController extends MouseAdapter {
1187:            JTree tree;
1188:            TreePacksPanel treePacksPanel;
1189:            int checkWidth = new JCheckBox().getPreferredSize().width;
1190:
1191:            public CheckTreeController(TreePacksPanel p) {
1192:                this .tree = p.getTree();
1193:                this .treePacksPanel = p;
1194:            }
1195:
1196:            private void selectNode(CheckBoxNode current) {
1197:                current.setPartial(false);
1198:                treePacksPanel.setModelValue(current);
1199:                Enumeration e = current.depthFirstEnumeration();
1200:                while (e.hasMoreElements()) {
1201:                    CheckBoxNode child = (CheckBoxNode) e.nextElement();
1202:                    child.setSelected(current.isSelected()
1203:                            || child.getPack().required);
1204:                    if (!child.isSelected())
1205:                        child.setPartial(false);
1206:                    treePacksPanel.setModelValue(child);
1207:                }
1208:                treePacksPanel.fromModel();
1209:            }
1210:
1211:            private boolean hasExcludes(CheckBoxNode node) {
1212:                Enumeration e = node.depthFirstEnumeration();
1213:                while (e.hasMoreElements()) {
1214:                    CheckBoxNode cbn = (CheckBoxNode) e.nextElement();
1215:                    if (cbn.getPack().excludeGroup != null)
1216:                        return true;
1217:                }
1218:                return false;
1219:            }
1220:
1221:            public void mouseReleased(MouseEvent me) {
1222:                TreePath path = tree.getPathForLocation(me.getX(), me.getY());
1223:                if (path == null)
1224:                    return;
1225:                CheckBoxNode current = (CheckBoxNode) path
1226:                        .getLastPathComponent();
1227:                treePacksPanel.setDescription(current.getId());
1228:                treePacksPanel.setDependencies(current.getId());
1229:                if (me.getX() > tree.getPathBounds(path).x + checkWidth)
1230:                    return;
1231:
1232:                // If this pack is required, leave it alone
1233:                if (current.getPack().required)
1234:                    return;
1235:
1236:                boolean currIsSelected = current.isSelected()
1237:                        & !current.isPartial();
1238:                boolean currIsPartial = current.isPartial();
1239:                boolean currHasExcludes = hasExcludes(current);
1240:                CheckBoxNode root = (CheckBoxNode) current.getRoot();
1241:
1242:                if (currIsPartial && currHasExcludes) {
1243:                    current.setSelected(false);
1244:                    selectNode(current); // deselect actually
1245:                    updateAllParents(root);
1246:                } else {
1247:                    if (!currIsSelected)
1248:                        selectAllChildNodes(current);
1249:                    current.setSelected(!currIsSelected);
1250:                    selectNode(current);
1251:                    updateAllParents(root);
1252:                }
1253:
1254:                initTotalSize(root, true);
1255:
1256:                // must override the bytes being computed at packsModel
1257:                treePacksPanel.setBytes((int) root.getTotalSize());
1258:                treePacksPanel.showSpaceRequired();
1259:                tree.treeDidChange();
1260:            }
1261:
1262:            public void selectAllChildNodes(CheckBoxNode cbn) {
1263:                Enumeration e = cbn.children();
1264:                while (e.hasMoreElements()) {
1265:                    CheckBoxNode subCbn = (CheckBoxNode) e.nextElement();
1266:                    selectAllDependencies(subCbn);
1267:                    if (subCbn.getChildCount() > 0)
1268:                        selectAllChildNodes(subCbn);
1269:
1270:                    subCbn.setSelected(true);
1271:                    // we need this, because the setModel ignored disabled values
1272:                    subCbn.setEnabled(true);
1273:                    treePacksPanel.setModelValue(subCbn);
1274:                    subCbn.setEnabled(!subCbn.getPack().required);
1275:                }
1276:            }
1277:
1278:            public void selectAllDependencies(CheckBoxNode cbn) {
1279:                Pack pack = cbn.getPack();
1280:                List<String> deps = pack.getDependencies();
1281:                if (deps == null)
1282:                    return;
1283:                Iterator<String> e = deps.iterator();
1284:                while (e.hasNext()) {
1285:                    String depId = e.next();
1286:                    CheckBoxNode depCbn = treePacksPanel.getCbnById(depId);
1287:                    selectAllDependencies(depCbn);
1288:                    if (depCbn.getChildCount() > 0) {
1289:                        if (!depCbn.isSelected() || depCbn.isPartial())
1290:                            selectAllChildNodes(depCbn);
1291:                    }
1292:                    depCbn.setSelected(true);
1293:                    // we need this, because the setModel ignored disabled values
1294:                    depCbn.setEnabled(true);
1295:                    treePacksPanel.setModelValue(depCbn);
1296:                    depCbn.setEnabled(!depCbn.getPack().required);
1297:                }
1298:            }
1299:
1300:            /**
1301:             * Updates partial/deselected/selected state of all parent nodes.
1302:             * This is needed and is a patch to allow unrelated nodes (in terms of the tree)
1303:             * to fire updates for each other.
1304:             * 
1305:             * @param root
1306:             */
1307:            public void updateAllParents(CheckBoxNode root) {
1308:                Enumeration rootEnum = root.depthFirstEnumeration();
1309:                while (rootEnum.hasMoreElements()) {
1310:                    CheckBoxNode child = (CheckBoxNode) rootEnum.nextElement();
1311:                    if (child.getParent() != null
1312:                            && !child.getParent().equals(root))
1313:                        updateParents(child);
1314:                }
1315:            }
1316:
1317:            /**
1318:             * Updates the parents of this particular node
1319:             * 
1320:             * @param node
1321:             */
1322:            private void updateParents(CheckBoxNode node) {
1323:                CheckBoxNode parent = (CheckBoxNode) node.getParent();
1324:                if (parent != null && !parent.equals(parent.getRoot())) {
1325:                    Enumeration ne = parent.children();
1326:                    boolean allSelected = true;
1327:                    boolean allDeselected = true;
1328:                    while (ne.hasMoreElements()) {
1329:                        CheckBoxNode child = (CheckBoxNode) ne.nextElement();
1330:                        if (child.isSelected())
1331:                            allDeselected = false;
1332:                        else
1333:                            allSelected = false;
1334:                        if (child.isPartial())
1335:                            allSelected = allDeselected = false;
1336:                        if (!allSelected && !allDeselected)
1337:                            break;
1338:                    }
1339:                    if (parent.getChildCount() > 0) {
1340:                        if (!allSelected && !allDeselected)
1341:                            setPartialParent(parent);
1342:                        else
1343:                            parent.setPartial(false);
1344:                        if (allSelected)
1345:                            parent.setSelected(true);
1346:                        if (allDeselected)
1347:                            parent.setSelected(false);
1348:                        treePacksPanel.setModelValue(parent);
1349:                        if (allSelected || allDeselected)
1350:                            updateParents(parent);
1351:                    }
1352:                    //updateTotalSize(node);
1353:                }
1354:            }
1355:
1356:            public static void setPartialParent(CheckBoxNode node) {
1357:                node.setPartial(true);
1358:                CheckBoxNode parent = (CheckBoxNode) node.getParent();
1359:                if (parent != null && !parent.equals(parent.getRoot()))
1360:                    setPartialParent(parent);
1361:            }
1362:
1363:            public static long initTotalSize(CheckBoxNode node,
1364:                    boolean markChanged) {
1365:                if (node.isLeaf())
1366:                    return node.getPack().nbytes;
1367:                Enumeration e = node.children();
1368:                Pack nodePack = node.getPack();
1369:                long bytes = 0;
1370:                if (nodePack != null)
1371:                    bytes = nodePack.nbytes;
1372:                while (e.hasMoreElements()) {
1373:                    CheckBoxNode c = (CheckBoxNode) e.nextElement();
1374:                    long size = initTotalSize(c, markChanged);
1375:                    if (c.isSelected() || c.isPartial()) {
1376:                        bytes += size;
1377:                    }
1378:                }
1379:                if (markChanged) {
1380:                    long old = node.getTotalSize();
1381:                    if (old != bytes)
1382:                        node.setTotalSizeChanged(true);
1383:                    else
1384:                        node.setTotalSizeChanged(false);
1385:                }
1386:                node.setTotalSize(bytes);
1387:                return bytes;
1388:            }
1389:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.