Statistics
| Revision:

root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / panels / PacksPanelBase.java @ 15280

History | View | Annotate | Download (17.9 KB)

1
/*
2
 *  $Id: PacksPanelBase.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
3
 *  IzPack
4
 *  Copyright (C) 2001-2004 Julien Ponge
5
 *
6
 *  File :               PacksPanel.java
7
 *  Description :        Base panel to select the packs to install.
8
 *  Author's email :     julien@izforge.com
9
 *  Author's Website :   http://www.izforge.com
10
 *
11
 *  Portions are Copyright (C) 2002 Marcus Wolschon
12
 *  Portions are Copyright (C) 2002 Jan Blok (jblok@profdata.nl - PDM - www.profdata.nl)
13
 *  Portions are Copyright (C) 2004 Klaus Bartz
14
 *
15
 *  This program is free software; you can redistribute it and/or
16
 *  modify it under the terms of the GNU General Public License
17
 *  as published by the Free Software Foundation; either version 2
18
 *  of the License, or any later version.
19
 *
20
 *  This program is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  You should have received a copy of the GNU General Public License
26
 *  along with this program; if not, write to the Free Software
27
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28
 */
29
package com.izforge.izpack.panels;
30

    
31
import java.awt.Color;
32
import java.awt.Component;
33
import java.awt.Dimension;
34
import java.awt.GridBagConstraints;
35
import java.awt.GridBagLayout;
36
import java.awt.Insets;
37
import java.awt.event.ActionEvent;
38
import java.awt.event.ActionListener;
39
import java.io.File;
40
import java.util.HashMap;
41
import java.util.List;
42
import java.util.Map;
43

    
44
import javax.swing.AbstractCellEditor;
45
import javax.swing.BorderFactory;
46
import javax.swing.Box;
47
import javax.swing.BoxLayout;
48
import javax.swing.JCheckBox;
49
import javax.swing.JLabel;
50
import javax.swing.JOptionPane;
51
import javax.swing.JPanel;
52
import javax.swing.JScrollPane;
53
import javax.swing.JTable;
54
import javax.swing.JTextArea;
55
import javax.swing.ListSelectionModel;
56
import javax.swing.border.Border;
57
import javax.swing.event.ListSelectionEvent;
58
import javax.swing.event.ListSelectionListener;
59
import javax.swing.table.DefaultTableCellRenderer;
60
import javax.swing.table.TableCellEditor;
61
import javax.swing.table.TableCellRenderer;
62

    
63
import net.n3.nanoxml.XMLElement;
64

    
65
import com.izforge.izpack.LocaleDatabase;
66
import com.izforge.izpack.Pack;
67
import com.izforge.izpack.gui.LabelFactory;
68
import com.izforge.izpack.installer.InstallData;
69
import com.izforge.izpack.installer.InstallerFrame;
70
import com.izforge.izpack.installer.IzPanel;
71
import com.izforge.izpack.installer.ResourceManager;
72
import com.izforge.izpack.util.IoHelper;
73

    
74
/**
75
 * The base class for Packs panels. It brings the common
76
 * member and methods of the different packs panels together.
77
 * This class handles the common logic of pack selection.
78
 * The derived class should be create the layout
79
 * and other specific actions.
80
 * There are some helper methods to simplify layout creation
81
 * in the derived class.
82
 *
83
 * @author     Julien Ponge
84
 * @author     Klaus Bartz
85
 */
86
public abstract class PacksPanelBase extends IzPanel implements PacksPanelInterface, ListSelectionListener
87
{
88
  // Common used Swing fields
89
  /**  The free space label. */
90
  protected JLabel freeSpaceLabel;
91

    
92
  /**  The space label. */
93
  protected JLabel spaceLabel;
94

    
95
  /**  The tip label. */
96
  protected JTextArea descriptionArea;
97

    
98
  /**  The dependencies label. */
99
  protected JTextArea dependencyArea;
100

    
101
  /**  The packs table. */
102
  protected JTable packsTable;
103

    
104
  /**  The tablescroll. */
105
  protected JScrollPane tableScroller;
106

    
107
 // Non-GUI fields
108
  /** Map that connects names with pack objects */
109
  private Map names;
110

    
111
  /**  The bytes of the current pack. */
112
  protected int bytes = 0;
113

    
114
  /**  The free bytes of the current selected disk. */
115
  protected long freeBytes = 0;
116

    
117
  /** Are there dependencies in the packs */
118
  protected boolean dependenciesExist = false;
119

    
120
  /** The packs locale database. */
121
  private LocaleDatabase langpack = null;
122

    
123
  /** The name of the XML file that specifies the panel langpack */
124
  private static final String LANG_FILE_NAME = "packsLang.xml";
125

    
126

    
127
  /**
128
   *  The constructor.
129
   *
130
   * @param  parent  The parent window.
131
   * @param  idata   The installation data.
132
   */
133
  public PacksPanelBase(InstallerFrame parent, InstallData idata)
134
  {
135
    super(parent, idata);
136
    // Load langpack.
137
    try
138
    {
139
      String resource = LANG_FILE_NAME + "_" + idata.localeISO3;
140
      this.langpack =
141
        new LocaleDatabase(ResourceManager.getInstance().getInputStream(resource));
142
    }
143
    catch (Throwable exception)
144
    {}
145
    //init the map
146
    computePacks(idata.availablePacks);
147

    
148
    createNormalLayout();
149
  }
150

    
151
  /**
152
   * The Implementation of this method should create the layout
153
   * for the current class.
154
   */
155
  abstract protected void createNormalLayout();
156

    
157
  /* (non-Javadoc)
158
   * @see com.izforge.izpack.panels.PacksPanelInterface#getLangpack()
159
   */
160
  public LocaleDatabase getLangpack()
161
  {
162
    return( langpack);
163
  }
164

    
165
  /* (non-Javadoc)
166
   * @see com.izforge.izpack.panels.PacksPanelInterface#getBytes()
167
   */
168
  public int getBytes()
169
  {
170
    return(bytes);
171
  }
172

    
173
  /* (non-Javadoc)
174
   * @see com.izforge.izpack.panels.PacksPanelInterface#setBytes(int)
175
   */
176
  public void setBytes(int bytes)
177
  {
178
    this.bytes = bytes;
179
  }
180

    
181
  /* (non-Javadoc)
182
   * @see com.izforge.izpack.panels.PacksPanelInterface#showSpaceRequired()
183
   */
184
  public void showSpaceRequired()
185
  {
186
    if( spaceLabel != null )
187
      spaceLabel.setText(Pack.toByteUnitsString(bytes));
188
  }
189

    
190
  /* (non-Javadoc)
191
   * @see com.izforge.izpack.panels.PacksPanelInterface#showFreeSpace()
192
   */
193
  public void showFreeSpace()
194
  {
195
    if( IoHelper.supported( "getFreeSpace") &&
196
    freeSpaceLabel != null )
197
    {
198
      String msg = null;
199
      freeBytes = IoHelper.getFreeSpace( IoHelper.existingParent(
200
      new File( idata.getInstallPath())).getAbsolutePath());
201
      if( freeBytes > 0x000000007fffffff )
202
        msg = " > 2 GB";
203
      else if( freeBytes < 0 )
204
        msg = parent.langpack.getString("PacksPanel.notAscertainable");
205
      else
206
        msg = Pack.toByteUnitsString((int) freeBytes);
207
      freeSpaceLabel.setText( msg );
208
    }
209
  }
210
  /**
211
   * Indicates wether the panel has been validated or not.
212
   *
213
   * @return    true if the needed space is less than the free space,
214
   * else false
215
   */
216
  public boolean isValidated()
217
  {
218
    if( IoHelper.supported("getFreeSpace") &&
219
       freeBytes >= 0 && freeBytes <= bytes )
220
    {
221
      JOptionPane.showMessageDialog(
222
          this,
223
          parent.langpack.getString("PacksPanel.notEnoughSpace"),
224
          parent.langpack.getString("installer.error"),
225
          JOptionPane.ERROR_MESSAGE);
226
      return(false);
227
    }
228
    return(true);
229
  }
230
  /**
231
   *  Asks to make the XML panel data.
232
   *
233
   * @param  panelRoot  The XML tree to write the data in.
234
   */
235
  public void makeXMLData(XMLElement panelRoot)
236
  {
237
    new ImgPacksPanelAutomationHelper().makeXMLData(idata, panelRoot);
238
  }
239

    
240
  /* (non-Javadoc)
241
   * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
242
   */
243
  public void valueChanged(ListSelectionEvent e)
244
  {
245
    int i = packsTable.getSelectedRow();
246
    if( i < 0 )
247
      return;
248
    //Operations for the description
249
    if( descriptionArea != null)
250
    {
251
     Pack pack = (Pack) idata.availablePacks.get(i);
252
     String desc = "";
253
     String key = pack.id+".description";
254
     if (langpack != null && pack.id != null && !pack.id.equals(""))
255
     {
256
       desc = langpack.getString(key);
257
     }
258
     if (desc.equals("") || key.equals(desc))
259
     {
260
       desc = pack.description;
261
     }
262
     descriptionArea.setText(desc);
263
   }
264
     //Operation for the dependency listing
265
    if(dependencyArea != null)
266
    {
267
      Pack pack = (Pack) idata.availablePacks.get(i);
268
      List dep = pack.dependencies;
269
      String list="";
270
      for (int j = 0; dep != null && j < dep.size(); j++)
271
      {
272
        String name = (String)dep.get(j);
273
        //Internationalization code
274
        Pack childPack = (Pack)names.get(name);
275
        String childName = "";
276
        String key = childPack.id;
277
        if (langpack != null && childPack.id != null && !childPack.id.equals(""))
278
        {
279
          childName = langpack.getString(key);
280
        }
281
        if  (childName.equals("") || key.equals(childName))
282
        {
283
          childName = childPack.name;
284
        }
285
        //End internationalization
286
        list += childName;
287
        if(j != dep.size()-1)
288
          list +=", ";
289
      }
290
      dependencyArea.setText(list);
291
    }
292
  }
293

    
294
  /**
295
   * Layout helper method:<br>
296
   * Creates an label with a message given by msgId and an
297
   * icon given by the iconId. If layout and constraints
298
   * are not null, the label will be added to layout
299
   * with the given constraints.
300
   * The label will be added to this object.
301
   * @param msgId identifier for the IzPack langpack
302
   * @param iconId identifier for the IzPack icons
303
   * @param layout layout to be used
304
   * @param constraints constraints to be used
305
   * @return the created label
306
   */
307
  protected JLabel createLabel( String msgId, String iconId,
308
    GridBagLayout layout,GridBagConstraints constraints )
309
  {
310
    JLabel label =
311
      LabelFactory.create(
312
        parent.langpack.getString(msgId),
313
        parent.icons.getImageIcon(iconId),
314
        JLabel.TRAILING);
315
    if( layout != null && constraints != null)
316
      layout.addLayoutComponent(label, constraints);
317
    add(label);
318
    return( label );
319
  }
320

    
321
  /**
322
   * Creates a panel containing a anonymous label on
323
   * the left with the message for the given msgId and
324
   * a label on the right side with initial no text.
325
   * The right label will be returned.
326
   * If layout and constraints are not null, the label
327
   * will be added to layout with the given constraints.
328
   * The panel will be added to this object.
329
   * @param msgId identifier for the IzPack langpack
330
   * @param layout layout to be used
331
   * @param constraints constraints to be used
332
   * @return the created (right) label
333
   */
334
  protected JLabel createPanelWithLabel(String msgId,
335
    GridBagLayout layout,GridBagConstraints constraints )
336
  {
337
    JPanel panel = new JPanel();
338
    JLabel label = new JLabel();
339
    if( label == null )
340
      label = new JLabel("");
341
    panel.setAlignmentX(LEFT_ALIGNMENT);
342
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
343
    panel.add(LabelFactory.create(parent.langpack.getString(msgId)));
344
    panel.add(Box.createHorizontalGlue());
345
    panel.add(label);
346
    if( layout != null && constraints != null)
347
      layout.addLayoutComponent(panel, constraints);
348
    add(panel);
349
    return( label);
350
  }
351
  /**
352
   * Creates a text area with standard settings and the
353
   * title given by the msgId.
354
   * If scroller is not null, the create text area will be
355
   * added to the scroller and the scroller to this object,
356
   * else the text area will be added directly to this object.
357
   * If layout and constraints are not null, the text area
358
   * or scroller will be added to layout with the given constraints.
359
   * The text area will be returned.
360
   * @param msgId identifier for the IzPack langpack
361
   * @param scroller the scroller to be used
362
   * @param layout layout to be used
363
   * @param constraints constraints to be used
364
   * @return the created text area
365
   */
366
  protected JTextArea createTextArea( String msgId, JScrollPane scroller,
367
    GridBagLayout layout,GridBagConstraints constraints )
368
  {
369
    JTextArea area = new JTextArea();
370
    area.setMargin(new Insets(2, 2, 2, 2));
371
    area.setAlignmentX(LEFT_ALIGNMENT);
372
    area.setCaretPosition(0);
373
    area.setEditable(false);
374
    area.setEditable(false);
375
    area.setOpaque(false);
376
    area.setLineWrap(true);
377
    area.setWrapStyleWord(true);
378
    area.setBorder(
379
      BorderFactory.createTitledBorder(
380
        parent.langpack.getString(msgId)));
381

    
382
    if(layout != null && constraints != null)
383
    {
384
      if( scroller != null )
385
      {
386
        layout.addLayoutComponent(scroller, constraints);
387
      }
388
      else
389
        layout.addLayoutComponent(area, constraints);
390
    }
391
    if( scroller != null )
392
    {
393
      scroller.setViewportView(area);
394
      add(scroller);
395
    }
396
    else
397
      add(area);
398
    return(area);
399

    
400
  }
401

    
402
  /**
403
   * Creates the table for the packs. All
404
   * parameters are required.
405
   * The table will be returned.
406
   * @param width of the table
407
   * @param scroller the scroller to be used
408
   * @param layout layout to be used
409
   * @param constraints constraints to be used
410
   * @return the created table
411
   */
412
  protected JTable createPacksTable(int width, JScrollPane scroller,
413
    GridBagLayout layout,GridBagConstraints constraints)
414
  {
415

    
416
    JTable table = new JTable();
417
    table.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
418
    table.setIntercellSpacing(new Dimension(0, 0));
419
    table.setBackground(Color.white);
420
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
421
    table.getSelectionModel().addListSelectionListener(this);
422
    table.setShowGrid(false);
423
    scroller.setViewportView(table);
424
    scroller.setAlignmentX(LEFT_ALIGNMENT);
425
    scroller.getViewport().setBackground(Color.white);
426
    scroller.setPreferredSize(
427
      new Dimension(width, (idata.guiPrefs.height / 3 + 30)));
428

    
429
    if( layout != null && constraints != null)
430
      layout.addLayoutComponent(scroller, constraints);
431
    add(scroller);
432
    return( table);
433
  }
434

    
435
  /**
436
   * Computes pack related data like the
437
   * names or the dependencies state.
438
   * @param packs
439
   */
440
  private void computePacks(List packs)
441
  {
442
    names = new HashMap();
443
    dependenciesExist = false;
444
    for (int i = 0; i < packs.size(); i++)
445
    {
446
      Pack pack = (Pack) packs.get(i);
447
      names.put(pack.name,pack);
448
      if( pack.dependencies != null)
449
        dependenciesExist = true;
450
    }
451
  }
452

    
453
  /**
454
   * Called when the panel becomes active.
455
   * If a derived class implements this method also, it
456
   * is recomanded to call this method with the super operator
457
   * first.
458
   *
459
   */
460
  public void panelActivate()
461
  {
462
    try
463
    {
464
      packsTable.setModel(
465
        new PacksModel(idata.availablePacks, idata.selectedPacks,this));
466
      CheckBoxEditorRenderer packSelectedRenderer =
467
        new CheckBoxEditorRenderer(false);
468
      packsTable.getColumnModel().getColumn(0).setCellRenderer(
469
        packSelectedRenderer);
470
      CheckBoxEditorRenderer packSelectedEditor =
471
        new CheckBoxEditorRenderer(true);
472
      packsTable.getColumnModel().getColumn(0).setCellEditor(
473
        packSelectedEditor);
474
      packsTable.getColumnModel().getColumn(0).setMaxWidth(40);
475
      DefaultTableCellRenderer renderer1 = new DefaultTableCellRenderer()
476
      {
477
        public void setBorder(Border b)
478
        {
479
        }
480
      };
481
      packsTable.getColumnModel().getColumn(1).setCellRenderer(renderer1);
482
      DefaultTableCellRenderer renderer2 = new DefaultTableCellRenderer()
483
      {
484
        public void setBorder(Border b)
485
        {
486
        }
487

    
488
          //          public void setFont(Font f)
489
    //          {
490
    //              super.setFont(new Font("Monospaced",Font.PLAIN,11));
491
    //          }
492
  };
493
      renderer2.setHorizontalAlignment(JLabel.RIGHT);
494
      packsTable.getColumnModel().getColumn(2).setCellRenderer(renderer2);
495
      packsTable.getColumnModel().getColumn(2).setMaxWidth(100);
496

    
497
      //remove header,so we don't need more strings
498
      tableScroller.remove(packsTable.getTableHeader());
499
      tableScroller.setColumnHeaderView(null);
500
      tableScroller.setColumnHeader(null);
501

    
502
      // set the JCheckBoxes to the currently selected panels. The selection might have changed in another panel
503
      java.util.Iterator iter = idata.availablePacks.iterator();
504
      bytes = 0;
505
      while (iter.hasNext())
506
      {
507
        Pack p = (Pack) iter.next();
508
        if (p.required)
509
        {
510
          bytes += p.nbytes;
511
          continue;
512
        }
513
        if (idata.selectedPacks.contains(p))
514
          bytes += p.nbytes;
515
      }
516
    } catch (Exception e)
517
    {
518
      e.printStackTrace();
519
    }
520
    showSpaceRequired();
521
    showFreeSpace();
522
  }
523

    
524
  static class CheckBoxEditorRenderer
525
    extends AbstractCellEditor
526
    implements TableCellRenderer, TableCellEditor, ActionListener
527
  {
528
    private JCheckBox display;
529
    public CheckBoxEditorRenderer(boolean useAsEditor)
530
    {
531
      display = new JCheckBox();
532
      display.setHorizontalAlignment(JLabel.CENTER);
533
      if (useAsEditor)
534
        display.addActionListener(this);
535

    
536
    }
537

    
538
    public Component getTableCellRendererComponent(
539
      JTable table,
540
      Object value,
541
      boolean isSelected,
542
      boolean hasFocus,
543
      int row,
544
      int column)
545
    {
546
      if (isSelected)
547
      {
548
        display.setForeground(table.getSelectionForeground());
549
        display.setBackground(table.getSelectionBackground());
550
      } else
551
      {
552
        display.setForeground(table.getForeground());
553
        display.setBackground(table.getBackground());
554
      }
555
      int state = ((Integer) value).intValue();
556
      display.setSelected((value != null && Math.abs(state) == 1));
557
      display.setEnabled(state >= 0);
558
      return display;
559
    }
560
    /**
561
     * @see javax.swing.table.TableCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int)
562
     */
563
    public Component getTableCellEditorComponent(
564
      JTable table,
565
      Object value,
566
      boolean isSelected,
567
      int row,
568
      int column)
569
    {
570
      return getTableCellRendererComponent(
571
        table,
572
        value,
573
        isSelected,
574
        false,
575
        row,
576
        column);
577
    }
578

    
579
    public Object getCellEditorValue()
580
    {
581
      return new Integer(display.isSelected() ? 1 : 0);
582
    }
583

    
584
    public void actionPerformed(ActionEvent e)
585
    {
586
      stopCellEditing();
587
    }
588
  }
589

    
590

    
591
}