KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > izforge > izpack > panels > InstallationGroupPanel


1 /*
2  * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
3  *
4  * http://www.izforge.com/izpack/
5  * http://developer.berlios.de/projects/izpack/
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19 package com.izforge.izpack.panels;
20
21 import java.awt.Component JavaDoc;
22 import java.awt.Dimension JavaDoc;
23 import java.awt.GridBagConstraints JavaDoc;
24 import java.awt.GridBagLayout JavaDoc;
25 import java.awt.Insets JavaDoc;
26 import java.awt.event.ItemEvent JavaDoc;
27 import java.awt.event.ItemListener JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.Comparator JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.Set JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.HashSet JavaDoc;
35
36 import javax.swing.AbstractCellEditor JavaDoc;
37 import javax.swing.BorderFactory JavaDoc;
38 import javax.swing.ButtonGroup JavaDoc;
39 import javax.swing.JRadioButton JavaDoc;
40 import javax.swing.JScrollPane JavaDoc;
41 import javax.swing.JTable JavaDoc;
42 import javax.swing.ListSelectionModel JavaDoc;
43 import javax.swing.JTextPane JavaDoc;
44 import javax.swing.border.EmptyBorder JavaDoc;
45 import javax.swing.border.TitledBorder JavaDoc;
46 import javax.swing.event.ListSelectionEvent JavaDoc;
47 import javax.swing.event.ListSelectionListener JavaDoc;
48 import javax.swing.table.DefaultTableModel JavaDoc;
49 import javax.swing.table.TableCellEditor JavaDoc;
50 import javax.swing.table.TableCellRenderer JavaDoc;
51 import javax.swing.table.TableColumnModel JavaDoc;
52 import javax.swing.table.TableModel JavaDoc;
53
54 import net.n3.nanoxml.XMLElement;
55
56 import com.izforge.izpack.Pack;
57 import com.izforge.izpack.installer.InstallData;
58 import com.izforge.izpack.installer.InstallerFrame;
59 import com.izforge.izpack.installer.IzPanel;
60 import com.izforge.izpack.util.Debug;
61 import com.izforge.izpack.util.AbstractUIHandler;
62
63 import java.util.ArrayList JavaDoc;
64 import java.net.URLDecoder JavaDoc;
65 import java.io.UnsupportedEncodingException JavaDoc;
66
67
68 /**
69  * A panel which displays the available installGroups found on the packs to
70  * allow the user to select a subset of the packs based on the pack
71  * installGroups attribute. This panel will be skipped if there are no
72  * pack elements with an installGroups attribute.
73  *
74  * @author Scott.Stark@jboss.org
75  * @version $Revision: 1.1.1.1 $
76  */

77 public class InstallationGroupPanel extends IzPanel
78     implements ListSelectionListener JavaDoc
79 {
80     private static final long serialVersionUID = 1L;
81
82     /** HashMap<String, Pack> of the InstallData.availablePacks */
83     private HashMap JavaDoc packsByName;
84     private TableModel JavaDoc groupTableModel;
85     private JTextPane JavaDoc descriptionField;
86     private JScrollPane JavaDoc groupScrollPane;
87     private JTable JavaDoc groupsTable;
88     private GroupData[] rows;
89     private int selectedGroup = -1;
90
91     public InstallationGroupPanel(InstallerFrame parent, InstallData idata)
92     {
93         super(parent, idata);
94         buildLayout();
95     }
96
97     /**
98      * If there are no packs with an installGroups attribute, this panel is
99      * skipped. Otherwise, the unique installGroups are displayed in a table.
100      */

101     public void panelActivate()
102     {
103         // Set/restore availablePacks from allPacks
104
idata.availablePacks = new ArrayList JavaDoc(idata.allPacks);
105
106         Debug.trace("InstallationGroupPanel.panelActivate, selectedGroup="+selectedGroup);
107         // If there are no groups, skip this panel
108
HashMap JavaDoc installGroups = getInstallGroups(idata);
109         if (installGroups.size() == 0)
110         {
111             super.askQuestion("Skip InstallGroup selection",
112                 "Skip InstallGroup selection", AbstractUIHandler.CHOICES_YES_NO);
113             parent.skipPanel();
114             return;
115         }
116
117         // Build the table model from the unique groups
118
groupTableModel = getModel(installGroups);
119         groupsTable.setModel(groupTableModel);
120         TableColumnModel JavaDoc tcm = groupsTable.getColumnModel();
121         tcm.getColumn(0).setCellRenderer(new RadioButtonRenderer());
122         tcm.getColumn(0).setCellEditor(new RadioButtonEditor());
123         //groupsTable.setColumnSelectionAllowed(false);
124
//groupsTable.setRowSelectionAllowed(true);
125
groupsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
126         groupsTable.getSelectionModel().addListSelectionListener (this);
127         groupsTable.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
128         groupsTable.setIntercellSpacing(new Dimension JavaDoc(0, 0));
129         groupsTable.setShowGrid(false);
130         if( selectedGroup >= 0 )
131         {
132             groupsTable.getSelectionModel().setSelectionInterval(selectedGroup, selectedGroup);
133             descriptionField.setText(rows[selectedGroup].description);
134         }
135         else
136         {
137             descriptionField.setText(rows[0].description);
138         }
139     }
140
141     /**
142      * Remove all packs from the InstallData availablePacks and selectedPacks
143      * that do not list the selected installation group. Packs without any
144      * installGroups are always included.
145      */

146     public void panelDeactivate()
147     {
148
149         Debug.trace("InstallationGroupPanel.panelDeactivate, selectedGroup="+selectedGroup);
150         if( selectedGroup >= 0 )
151         {
152             removeUnusedPacks();
153             GroupData group = this.rows[selectedGroup];
154             idata.setVariable("INSTALL_GROUP", group.name);
155             Debug.trace("Added variable INSTALL_GROUP="+group.name);
156         }
157     }
158
159     /**
160      * There needs to be a valid selectedGroup to go to the next panel
161      * @return true if selectedGroup >= 0, false otherwise
162      */

163     public boolean isValidated()
164     {
165         Debug.trace("InstallationGroupPanel.isValidated, selectedGroup="+selectedGroup);
166         return selectedGroup >= 0;
167     }
168
169     /**
170      * Update the current selected install group index.
171      * @param e
172      */

173     public void valueChanged(ListSelectionEvent JavaDoc e)
174     {
175         Debug.trace("valueChanged: " + e);
176         if (e.getValueIsAdjusting() == false)
177         {
178             ListSelectionModel JavaDoc lsm = (ListSelectionModel JavaDoc) e.getSource();
179             if( lsm.isSelectionEmpty() )
180             {
181                 descriptionField.setText("");
182             }
183             else
184             {
185                 selectedGroup = lsm.getMinSelectionIndex();
186                 if( selectedGroup >= 0 )
187                 {
188                     GroupData data = rows[selectedGroup];
189                     descriptionField.setText(data.description);
190                 }
191                 Debug.trace("selectedGroup set to: "+selectedGroup);
192             }
193         }
194     }
195
196     /* Add the installation group to pack mappings
197      * @see com.izforge.izpack.installer.IzPanel#makeXMLData(net.n3.nanoxml.XMLElement)
198      */

199     public void makeXMLData(XMLElement panelRoot)
200     {
201         InstallationGroupPanelAutomationHelper helper = new InstallationGroupPanelAutomationHelper();
202         idata.setAttribute("GroupData", rows);
203         idata.setAttribute("packsByName", packsByName);
204         helper.makeXMLData(idata, panelRoot);
205     }
206
207     /**
208      * Create the panel ui.
209      */

210     protected void buildLayout()
211     {
212         GridBagConstraints JavaDoc gridBagConstraints;
213
214         descriptionField = new JTextPane JavaDoc();
215         groupScrollPane = new JScrollPane JavaDoc();
216         groupsTable = new JTable JavaDoc();
217
218         setLayout(new GridBagLayout JavaDoc());
219
220         descriptionField.setMargin(new Insets JavaDoc(2, 2, 2, 2));
221         descriptionField.setAlignmentX(LEFT_ALIGNMENT);
222         descriptionField.setCaretPosition(0);
223         descriptionField.setEditable(false);
224         descriptionField.setOpaque(false);
225         descriptionField.setText("<b>Install group description text</b>");
226         descriptionField.setContentType("text/html");
227         descriptionField.setBorder(new TitledBorder JavaDoc("Description"));
228         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
229         gridBagConstraints.gridy = 2;
230         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
231         gridBagConstraints.weightx = 1.0;
232         gridBagConstraints.weighty = 0.3;
233         add(descriptionField, gridBagConstraints);
234
235         groupScrollPane.setBorder(new EmptyBorder JavaDoc(1, 1, 1, 1));
236         groupScrollPane.setViewportView(groupsTable);
237
238         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
239         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
240         gridBagConstraints.weightx = 1.0;
241         gridBagConstraints.weighty = 1.0;
242         add(groupScrollPane, gridBagConstraints);
243     }
244
245     protected void removeUnusedPacks()
246     {
247         GroupData data = rows[selectedGroup];
248         Debug.trace("InstallationGroupPanel.removeUnusedPacks, GroupData="+data.name);
249
250         // Now remove the packs not in groupPackNames
251
idata.selectedPacks.clear();
252         idata.selectedPacks.addAll(idata.availablePacks);
253         Iterator JavaDoc iter = idata.availablePacks.iterator();
254         while( iter.hasNext() )
255         {
256             Pack p = (Pack) iter.next();
257
258             //reverse dependencies must be reset in case the user is going
259
//back and forth between the group selection panel and the packs selection panel
260
p.revDependencies = null;
261
262             if( data.packNames.contains(p.name) == false )
263             {
264                 iter.remove();
265                 Debug.trace("Removed AvailablePack: "+p.name);
266             }
267         }
268
269         List JavaDoc selectedPacks = idata.selectedPacks;
270         iter = selectedPacks.iterator();
271         while( iter.hasNext() )
272         {
273             Pack p = (Pack) iter.next();
274             if( data.packNames.contains(p.name) == false )
275             {
276                 iter.remove();
277                 Debug.trace("Removed selectedPack: "+p.name);
278             }
279         }
280     }
281     protected void addDependents(Pack p, HashMap JavaDoc packsByName, GroupData data)
282     {
283         data.packNames.add(p.name);
284         data.size += p.nbytes;
285         Debug.trace("addDependents, added pack: "+p.name);
286         if( p.dependencies == null || p.dependencies.size() == 0 )
287             return;
288
289         Iterator JavaDoc iter = p.dependencies.iterator();
290         Debug.trace(p.name+" dependencies: "+p.dependencies);
291         while( iter.hasNext() )
292         {
293             String JavaDoc dependent = (String JavaDoc) iter.next();
294             if( data.packNames.contains(dependent) == false )
295             {
296                 Debug.trace("Need dependent: "+dependent);
297                 Pack dependentPack = (Pack) packsByName.get(dependent);
298                 addDependents(dependentPack, packsByName, data);
299             }
300         }
301     }
302
303     /**
304      * Build the set of unique installGroups data. The GroupData description
305      * is taken from the InstallationGroupPanel.description.[name] property
306      * where [name] is the installGroup name. The GroupData size is built
307      * from the Pack.nbytes sum.
308      *
309      * @param idata - the panel install data
310      * @return HashMap<String, GroupData> of unique install group names
311      */

312     protected HashMap JavaDoc getInstallGroups(InstallData idata)
313     {
314         /* First create a packsByName<String, Pack> of all packs and identify
315         the unique install group names.
316         */

317         packsByName = new HashMap JavaDoc();
318         HashMap JavaDoc installGroups = new HashMap JavaDoc();
319         for (int n = 0; n < idata.availablePacks.size(); n++)
320         {
321             Pack p = (Pack) idata.availablePacks.get(n);
322             packsByName.put(p.name, p);
323             Set JavaDoc groups = p.installGroups;
324             Iterator JavaDoc iter = groups.iterator();
325             Debug.trace("Pack: "+p.name+", installGroups: "+groups);
326             while (iter.hasNext())
327             {
328                 String JavaDoc group = (String JavaDoc) iter.next();
329                 GroupData data = (GroupData) installGroups.get(group);
330                 if (data == null)
331                 {
332                     String JavaDoc description = getGroupDescription(group);
333                     data = new GroupData(group, description);
334                     installGroups.put(group, data);
335                 }
336             }
337         }
338         Debug.trace("Found installGroups: " + installGroups.keySet());
339
340         /* Build up a set of the packs to include in the installation by finding
341         all packs in the selected group, and then include their dependencies.
342         */

343         Iterator JavaDoc gditer = installGroups.values().iterator();
344         while( gditer.hasNext() )
345         {
346             GroupData data = (GroupData) gditer.next();
347             Debug.trace("Adding dependents for: "+data.name);
348             Iterator JavaDoc iter = idata.availablePacks.iterator();
349             while( iter.hasNext() )
350             {
351                 Pack p = (Pack) iter.next();
352                 Set JavaDoc groups = p.installGroups;
353                 if( groups.size() == 0 || groups.contains(data.name) == true )
354                 {
355                     // The pack may have already been added while traversing dependencies
356
if( data.packNames.contains(p.name) == false )
357                         addDependents(p, packsByName, data);
358                 }
359             }
360             Debug.trace("Completed dependents for: "+data);
361             if( Debug.tracing() )
362                 Debug.trace(data);
363         }
364
365         return installGroups;
366     }
367
368     /**
369      * Look for a key = InstallationGroupPanel.description.[group] entry:
370      * first using idata.langpack.getString(key+".html")
371      * next using idata.langpack.getString(key)
372      * next using idata.getVariable(key)
373      * lastly, defaulting to group + " installation"
374      * @param group - the installation group name
375      * @return the group description
376      */

377     protected String JavaDoc getGroupDescription(String JavaDoc group)
378     {
379         String JavaDoc description = null;
380         String JavaDoc key = "InstallationGroupPanel.description." + group;
381         if( idata.langpack != null )
382         {
383             String JavaDoc htmlKey = key+".html";
384             String JavaDoc html = idata.langpack.getString(htmlKey);
385             // This will equal the key if there is no entry
386
if( htmlKey.equalsIgnoreCase(html) )
387                 description = idata.langpack.getString(key);
388             else
389                 description = html;
390         }
391         if (description == null || key.equalsIgnoreCase(description))
392             description = idata.getVariable(key);
393         if (description == null)
394             description = group + " installation";
395         try
396         {
397             description = URLDecoder.decode(description, "UTF-8");
398         }
399         catch (UnsupportedEncodingException JavaDoc e)
400         {
401             emitWarning("Failed to convert description", e.getMessage());
402         }
403
404         return description;
405     }
406
407     protected TableModel JavaDoc getModel(HashMap JavaDoc groupData)
408     {
409         String JavaDoc[] columns = { "Selected", "InstallType", "Size"};
410          DefaultTableModel JavaDoc model = new DefaultTableModel JavaDoc (columns, 0)
411          {
412             public boolean isCellEditable (int row, int column)
413             {
414                return column == 0;
415             }
416         };
417         rows = new GroupData[groupData.size()];
418         // The name of the group to select if there is no current selection
419
String JavaDoc defaultGroup = idata.getVariable("InstallationGroupPanel.defaultGroup");
420          Debug.trace("InstallationGroupPanel.defaultGroup="+defaultGroup+", selectedGroup="+selectedGroup);
421          List JavaDoc values = new ArrayList JavaDoc(groupData.values());
422          Collections.sort(values, new Comparator JavaDoc()
423          {
424            public int compare(Object JavaDoc o1, Object JavaDoc o2)
425            {
426                GroupData g1 = (GroupData) o1;
427                GroupData g2 = (GroupData) o2;
428
429                if (g1.name == null || g2.name==null)
430                {
431                    return 0;
432                }
433
434                return g1.name.compareTo(g2.name);
435            }
436         });
437
438         Iterator JavaDoc iter = values.iterator();
439         ButtonGroup JavaDoc buttonGroup = new ButtonGroup JavaDoc();
440         boolean madeSelection = false;
441         int count = 0;
442         while (iter.hasNext())
443         {
444             GroupData gd = (GroupData) iter.next();
445             rows[count] = gd;
446             Debug.trace("Creating button#"+count+", group="+gd.name);
447             JRadioButton JavaDoc btn = new JRadioButton JavaDoc(gd.name);
448             if( selectedGroup == count )
449             {
450                 btn.setSelected(true);
451                 Debug.trace("Selected button#"+count);
452             }
453             else if ( selectedGroup < 0 && madeSelection == false )
454             {
455                 if( defaultGroup != null )
456                 {
457                    if( defaultGroup.equals(gd.name) )
458                      madeSelection = true;
459                 }
460                 else if( count == 0 )
461                     madeSelection = true;
462                 if( madeSelection )
463                 {
464                     btn.setSelected(true);
465                     Debug.trace("Selected button#"+count);
466                     selectedGroup = count;
467                 }
468             }
469             else
470             {
471                 btn.setSelected(false);
472             }
473             buttonGroup.add(btn);
474             String JavaDoc sizeText = gd.getSizeString();
475             Object JavaDoc[] data = { btn, gd.description, sizeText};
476             model.addRow(data);
477             count ++;
478         }
479         return model;
480     }
481
482     protected static class GroupData
483     {
484         static final long ONEK = 1024;
485         static final long ONEM = 1024 * 1024;
486         static final long ONEG = 1024 * 1024 * 1024;
487
488         String JavaDoc name;
489         String JavaDoc description;
490         long size;
491         HashSet JavaDoc packNames = new HashSet JavaDoc();
492
493         GroupData(String JavaDoc name, String JavaDoc description)
494         {
495             this.name = name;
496             this.description = description;
497         }
498
499         String JavaDoc getSizeString()
500         {
501             String JavaDoc s;
502             if (size < ONEK)
503             {
504                 s = size + " bytes";
505             }
506             else if (size < ONEM)
507             {
508                 s = size / ONEK + " KBytes";
509             }
510             else if (size < ONEG)
511             {
512                 s = size / ONEM + " MBytes";
513             }
514             else
515             {
516                 s = size / ONEG + " GBytes";
517             }
518             return s;
519         }
520         public String JavaDoc toString()
521         {
522             StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("GroupData(");
523             tmp.append(name);
524             tmp.append("){description=");
525             tmp.append(description);
526             tmp.append(", size=");
527             tmp.append(size);
528             tmp.append(", sizeString=");
529             tmp.append(getSizeString());
530             tmp.append(", packNames=");
531             tmp.append(packNames);
532             tmp.append("}");
533             return tmp.toString();
534         }
535     }
536
537     class RadioButtonRenderer implements TableCellRenderer JavaDoc
538     {
539         public Component JavaDoc getTableCellRendererComponent (JTable JavaDoc table, Object JavaDoc value,
540                                                         boolean isSelected, boolean hasFocus,
541                                                         int row, int column)
542         {
543             if (value==null) {
544                 return null;
545             }
546
547             JRadioButton JavaDoc button = (JRadioButton JavaDoc) value;
548
549             button.setForeground(isSelected ?
550                                  table.getSelectionForeground() : table.getForeground());
551             button.setBackground(isSelected ?
552                                  table.getSelectionBackground() : table.getBackground());
553
554             return button;
555         }
556     }
557
558     class RadioButtonEditor
559         extends AbstractCellEditor JavaDoc
560         implements ItemListener JavaDoc,
561                    TableCellEditor JavaDoc
562     {
563         private JRadioButton JavaDoc button;
564
565         public Component JavaDoc getTableCellEditorComponent (JTable JavaDoc table, Object JavaDoc value,
566                                                       boolean isSelected, int row, int column)
567         {
568             Debug.trace("getTableCellEditorComponent, row="+row);
569             if (value==null) {
570                 return null;
571             }
572
573             button = (JRadioButton JavaDoc) value;
574             button.addItemListener(this);
575
576             button.setForeground(isSelected ?
577                                  table.getSelectionForeground() : table.getForeground());
578             button.setBackground(isSelected ?
579                                  table.getSelectionBackground() : table.getBackground());
580
581             return button;
582         }
583
584         public Object JavaDoc getCellEditorValue ()
585         {
586             button.removeItemListener (this);
587             return button;
588         }
589
590         public void itemStateChanged (ItemEvent JavaDoc e)
591         {
592             Debug.trace("itemStateChanged, e="+e);
593             super.fireEditingStopped ();
594             groupsTable.repaint();
595         }
596     }
597
598 }
599
Popular Tags