001: /*
002: * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
003: *
004: * http://izpack.org/
005: * http://izpack.codehaus.org/
006: *
007: * Copyright 2002 Marcus Wolschon
008: * Copyright 2002 Jan Blok
009: * Copyright 2004 Klaus Bartz
010: * Copyright 2007 Dennis Reil
011: *
012: * Licensed under the Apache License, Version 2.0 (the "License");
013: * you may not use this file except in compliance with the License.
014: * You may obtain a copy of the License at
015: *
016: * http://www.apache.org/licenses/LICENSE-2.0
017: *
018: * Unless required by applicable law or agreed to in writing, software
019: * distributed under the License is distributed on an "AS IS" BASIS,
020: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
021: * See the License for the specific language governing permissions and
022: * limitations under the License.
023: */
024:
025: package com.izforge.izpack.panels;
026:
027: import java.awt.Color;
028: import java.awt.Component;
029: import java.awt.Dimension;
030: import java.awt.Graphics;
031: import java.awt.GridBagConstraints;
032: import java.awt.GridBagLayout;
033: import java.io.File;
034: import java.io.InputStream;
035: import java.util.HashMap;
036: import java.util.Iterator;
037: import java.util.List;
038: import java.util.Map;
039:
040: import javax.swing.BorderFactory;
041: import javax.swing.Box;
042: import javax.swing.BoxLayout;
043: import javax.swing.ButtonModel;
044: import javax.swing.Icon;
045: import javax.swing.JCheckBox;
046: import javax.swing.JLabel;
047: import javax.swing.JOptionPane;
048: import javax.swing.JPanel;
049: import javax.swing.JScrollPane;
050: import javax.swing.JTable;
051: import javax.swing.JTextArea;
052: import javax.swing.ListSelectionModel;
053: import javax.swing.event.ListSelectionEvent;
054: import javax.swing.event.ListSelectionListener;
055: import javax.swing.plaf.metal.MetalLookAndFeel;
056: import javax.swing.table.DefaultTableCellRenderer;
057: import javax.swing.table.TableCellRenderer;
058:
059: import net.n3.nanoxml.XMLElement;
060:
061: import com.izforge.izpack.LocaleDatabase;
062: import com.izforge.izpack.Pack;
063: import com.izforge.izpack.gui.LabelFactory;
064: import com.izforge.izpack.installer.Debugger;
065: import com.izforge.izpack.installer.InstallData;
066: import com.izforge.izpack.installer.InstallerFrame;
067: import com.izforge.izpack.installer.IzPanel;
068: import com.izforge.izpack.installer.ResourceManager;
069: import com.izforge.izpack.util.Debug;
070: import com.izforge.izpack.util.IoHelper;
071: import com.izforge.izpack.util.VariableSubstitutor;
072:
073: /**
074: * The base class for Packs panels. It brings the common member and methods of the different packs
075: * panels together. This class handles the common logic of pack selection. The derived class should
076: * be create the layout and other specific actions. There are some helper methods to simplify layout
077: * creation in the derived class.
078: *
079: * @author Julien Ponge
080: * @author Klaus Bartz
081: * @author Dennis Reil
082: */
083: public abstract class PacksPanelBase extends IzPanel implements
084: PacksPanelInterface, ListSelectionListener {
085:
086: // Common used Swing fields
087: /**
088: * The free space label.
089: */
090: protected JLabel freeSpaceLabel;
091:
092: /**
093: * The space label.
094: */
095: protected JLabel spaceLabel;
096:
097: /**
098: * The tip label.
099: */
100: protected JTextArea descriptionArea;
101:
102: /**
103: * The dependencies label.
104: */
105: protected JTextArea dependencyArea;
106:
107: /**
108: * The packs table.
109: */
110: protected JTable packsTable;
111:
112: /**
113: * The packs model.
114: */
115: protected PacksModel packsModel;
116:
117: /**
118: * The tablescroll.
119: */
120: protected JScrollPane tableScroller;
121:
122: // Non-GUI fields
123: /**
124: * Map that connects names with pack objects
125: */
126: private Map<String, Pack> names;
127:
128: /**
129: * The bytes of the current pack.
130: */
131: protected long bytes = 0;
132:
133: /**
134: * The free bytes of the current selected disk.
135: */
136: protected long freeBytes = 0;
137:
138: /**
139: * Are there dependencies in the packs
140: */
141: protected boolean dependenciesExist = false;
142:
143: /**
144: * The packs locale database.
145: */
146: private LocaleDatabase langpack = null;
147:
148: /**
149: * The name of the XML file that specifies the panel langpack
150: */
151: private static final String LANG_FILE_NAME = "packsLang.xml";
152:
153: private Debugger debugger;
154:
155: /**
156: * The constructor.
157: *
158: * @param parent The parent window.
159: * @param idata The installation data.
160: */
161: public PacksPanelBase(InstallerFrame parent, InstallData idata) {
162: super (parent, idata);
163: // Load langpack.
164: try {
165: this .langpack = parent.langpack;
166: InputStream inputStream = ResourceManager.getInstance()
167: .getInputStream(LANG_FILE_NAME);
168: this .langpack.add(inputStream);
169: this .debugger = parent.getDebugger();
170: } catch (Throwable exception) {
171: Debug.trace(exception);
172: }
173: // init the map
174: computePacks(idata.availablePacks);
175:
176: createNormalLayout();
177: }
178:
179: /**
180: * The Implementation of this method should create the layout for the current class.
181: */
182: abstract protected void createNormalLayout();
183:
184: /*
185: * (non-Javadoc)
186: *
187: * @see com.izforge.izpack.panels.PacksPanelInterface#getLangpack()
188: */
189: public LocaleDatabase getLangpack() {
190: return (langpack);
191: }
192:
193: /*
194: * (non-Javadoc)
195: *
196: * @see com.izforge.izpack.panels.PacksPanelInterface#getBytes()
197: */
198: public long getBytes() {
199: return bytes;
200: }
201:
202: /*
203: * (non-Javadoc)
204: *
205: * @see com.izforge.izpack.panels.PacksPanelInterface#setBytes(int)
206: */
207: public void setBytes(long bytes) {
208: this .bytes = bytes;
209: }
210:
211: /*
212: * (non-Javadoc)
213: *
214: * @see com.izforge.izpack.panels.PacksPanelInterface#showSpaceRequired()
215: */
216: public void showSpaceRequired() {
217: if (spaceLabel != null)
218: spaceLabel.setText(Pack.toByteUnitsString(bytes));
219: }
220:
221: /*
222: * (non-Javadoc)
223: *
224: * @see com.izforge.izpack.panels.PacksPanelInterface#showFreeSpace()
225: */
226: public void showFreeSpace() {
227: if (IoHelper.supported("getFreeSpace")
228: && freeSpaceLabel != null) {
229: String msg = null;
230: freeBytes = IoHelper
231: .getFreeSpace(IoHelper.existingParent(
232: new File(idata.getInstallPath()))
233: .getAbsolutePath());
234: if (freeBytes < 0)
235: msg = parent.langpack
236: .getString("PacksPanel.notAscertainable");
237: else
238: msg = Pack.toByteUnitsString(freeBytes);
239: freeSpaceLabel.setText(msg);
240: }
241: }
242:
243: /**
244: * Indicates wether the panel has been validated or not.
245: *
246: * @return true if the needed space is less than the free space, else false
247: */
248: public boolean isValidated() {
249: if (IoHelper.supported("getFreeSpace") && freeBytes >= 0
250: && freeBytes <= bytes) {
251: JOptionPane.showMessageDialog(this , parent.langpack
252: .getString("PacksPanel.notEnoughSpace"),
253: parent.langpack.getString("installer.error"),
254: JOptionPane.ERROR_MESSAGE);
255: return (false);
256: }
257: return (true);
258: }
259:
260: /**
261: * Asks to make the XML panel data.
262: *
263: * @param panelRoot The XML tree to write the data in.
264: */
265: public void makeXMLData(XMLElement panelRoot) {
266: new ImgPacksPanelAutomationHelper().makeXMLData(idata,
267: panelRoot);
268: }
269:
270: /*
271: * (non-Javadoc)
272: *
273: * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
274: */
275: public void valueChanged(ListSelectionEvent e) {
276: VariableSubstitutor vs = new VariableSubstitutor(idata
277: .getVariables());
278: int i = packsTable.getSelectedRow();
279: if (i < 0)
280: return;
281:
282: // toggle the value stored in the packsModel
283: if (e.getValueIsAdjusting()) {
284: Integer checked = (Integer) packsModel.getValueAt(i, 0);
285: checked = (checked == 0) ? 1 : 0;
286: packsModel.setValueAt(checked, i, 0);
287: }
288:
289: // Operations for the description
290: if (descriptionArea != null) {
291: Pack pack = (Pack) idata.availablePacks.get(i);
292: String desc = "";
293: String key = pack.id + ".description";
294: if (langpack != null && pack.id != null
295: && !"".equals(pack.id)) {
296: desc = langpack.getString(key);
297: }
298: if ("".equals(desc) || key.equals(desc)) {
299: desc = pack.description;
300: }
301: desc = vs.substitute(desc, null);
302: descriptionArea.setText(desc);
303: }
304: // Operation for the dependency listing
305: if (dependencyArea != null) {
306: Pack pack = (Pack) idata.availablePacks.get(i);
307: List<String> dep = pack.dependencies;
308: String list = "";
309: if (dep != null) {
310: list += (langpack == null) ? "Dependencies: "
311: : langpack.getString("PacksPanel.dependencies");
312: }
313: for (int j = 0; dep != null && j < dep.size(); j++) {
314: String name = dep.get(j);
315: list += getI18NPackName(names.get(name));
316: if (j != dep.size() - 1)
317: list += ", ";
318: }
319:
320: // add the list of the packs to be excluded
321: String excludeslist = (langpack == null) ? "Excludes: "
322: : langpack.getString("PacksPanel.excludes");
323: int numexcludes = 0;
324: if (pack.excludeGroup != null) {
325: for (int q = 0; q < idata.availablePacks.size(); q++) {
326: Pack otherpack = (Pack) idata.availablePacks.get(q);
327: String exgroup = otherpack.excludeGroup;
328: if (exgroup != null) {
329: if (q != i && pack.excludeGroup.equals(exgroup)) {
330:
331: excludeslist += getI18NPackName(otherpack)
332: + ", ";
333: numexcludes++;
334: }
335: }
336: }
337: }
338: // concatenate
339: if (dep != null)
340: excludeslist = " " + excludeslist;
341: if (numexcludes > 0)
342: list += excludeslist;
343: if (list.endsWith(", "))
344: list = list.substring(0, list.length() - 2);
345:
346: // and display the result
347: dependencyArea.setText(list);
348: }
349: }
350:
351: /**
352: * This method tries to resolve the localized name of the given pack. If this is not possible,
353: * the name given in the installation description file in ELEMENT <pack> will be used.
354: *
355: * @param pack for which the name should be resolved
356: * @return localized name of the pack
357: */
358: private String getI18NPackName(Pack pack) {
359: // Internationalization code
360: String packName = pack.name;
361: String key = pack.id;
362: if (langpack != null && pack.id != null && !"".equals(pack.id)) {
363: packName = langpack.getString(key);
364: }
365: if ("".equals(packName) || key == null || key.equals(packName)) {
366: packName = pack.name;
367: }
368: return (packName);
369: }
370:
371: /**
372: * Layout helper method:<br>
373: * Creates an label with a message given by msgId and an icon given by the iconId. If layout and
374: * constraints are not null, the label will be added to layout with the given constraints. The
375: * label will be added to this object.
376: *
377: * @param msgId identifier for the IzPack langpack
378: * @param iconId identifier for the IzPack icons
379: * @param layout layout to be used
380: * @param constraints constraints to be used
381: * @return the created label
382: */
383: protected JLabel createLabel(String msgId, String iconId,
384: GridBagLayout layout, GridBagConstraints constraints) {
385: JLabel label = LabelFactory.create(parent.langpack
386: .getString(msgId), parent.icons.getImageIcon(iconId),
387: TRAILING);
388: if (layout != null && constraints != null)
389: layout.addLayoutComponent(label, constraints);
390: add(label);
391: return (label);
392: }
393:
394: /**
395: * Creates a panel containing a anonymous label on the left with the message for the given msgId
396: * and a label on the right side with initial no text. The right label will be returned. If
397: * layout and constraints are not null, the label will be added to layout with the given
398: * constraints. The panel will be added to this object.
399: *
400: * @param msgId identifier for the IzPack langpack
401: * @param layout layout to be used
402: * @param constraints constraints to be used
403: * @return the created (right) label
404: */
405: protected JLabel createPanelWithLabel(String msgId,
406: GridBagLayout layout, GridBagConstraints constraints) {
407: JPanel panel = new JPanel();
408: JLabel label = new JLabel();
409: if (label == null)
410: label = new JLabel("");
411: panel.setAlignmentX(LEFT_ALIGNMENT);
412: panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
413: panel
414: .add(LabelFactory.create(parent.langpack
415: .getString(msgId)));
416: panel.add(Box.createHorizontalGlue());
417: panel.add(label);
418: if (layout != null && constraints != null)
419: layout.addLayoutComponent(panel, constraints);
420: add(panel);
421: return (label);
422: }
423:
424: /**
425: * Creates a text area with standard settings and the title given by the msgId. If scroller is
426: * not null, the create text area will be added to the scroller and the scroller to this object,
427: * else the text area will be added directly to this object. If layout and constraints are not
428: * null, the text area or scroller will be added to layout with the given constraints. The text
429: * area will be returned.
430: *
431: * @param msgId identifier for the IzPack langpack
432: * @param scroller the scroller to be used
433: * @param layout layout to be used
434: * @param constraints constraints to be used
435: * @return the created text area
436: */
437: protected JTextArea createTextArea(String msgId,
438: JScrollPane scroller, GridBagLayout layout,
439: GridBagConstraints constraints) {
440: JTextArea area = new JTextArea();
441: // area.setMargin(new Insets(2, 2, 2, 2));
442: area.setAlignmentX(LEFT_ALIGNMENT);
443: area.setCaretPosition(0);
444: area.setEditable(false);
445: area.setEditable(false);
446: area.setOpaque(false);
447: area.setLineWrap(true);
448: area.setWrapStyleWord(true);
449: area.setBorder(BorderFactory.createTitledBorder(parent.langpack
450: .getString(msgId)));
451: area.setFont(getControlTextFont());
452:
453: if (layout != null && constraints != null) {
454: if (scroller != null) {
455: layout.addLayoutComponent(scroller, constraints);
456: } else
457: layout.addLayoutComponent(area, constraints);
458: }
459: if (scroller != null) {
460: scroller.setViewportView(area);
461: add(scroller);
462: } else
463: add(area);
464: return (area);
465:
466: }
467:
468: /**
469: * Creates the table for the packs. All parameters are required. The table will be returned.
470: *
471: * @param width of the table
472: * @param scroller the scroller to be used
473: * @param layout layout to be used
474: * @param constraints constraints to be used
475: * @return the created table
476: */
477: protected JTable createPacksTable(int width, JScrollPane scroller,
478: GridBagLayout layout, GridBagConstraints constraints) {
479:
480: JTable table = new JTable();
481: table.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
482: table.setIntercellSpacing(new Dimension(0, 0));
483: table.setBackground(Color.white);
484: table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
485: table.getSelectionModel().addListSelectionListener(this );
486: table.setShowGrid(false);
487: scroller.setViewportView(table);
488: scroller.setAlignmentX(LEFT_ALIGNMENT);
489: scroller.getViewport().setBackground(Color.white);
490: scroller.setPreferredSize(new Dimension(width,
491: (idata.guiPrefs.height / 3 + 30)));
492:
493: if (layout != null && constraints != null)
494: layout.addLayoutComponent(scroller, constraints);
495: add(scroller);
496: return (table);
497: }
498:
499: /**
500: * Computes pack related data like the names or the dependencies state.
501: *
502: * @param packs
503: */
504: private void computePacks(List packs) {
505: names = new HashMap<String, Pack>();
506: dependenciesExist = false;
507: for (Object pack1 : packs) {
508: Pack pack = (Pack) pack1;
509: names.put(pack.name, pack);
510: if (pack.dependencies != null || pack.excludeGroup != null) {
511: dependenciesExist = true;
512: }
513: }
514: }
515:
516: /**
517: * Called when the panel becomes active. If a derived class implements this method also, it is
518: * recomanded to call this method with the super operator first.
519: */
520: public void panelActivate() {
521: try {
522:
523: // TODO the PacksModel could be patched such that isCellEditable
524: // allows returns false. In that case the PacksModel must not be
525: // adapted here.
526: packsModel = new PacksModel(this , idata, this .parent
527: .getRules()) {
528: /**
529: * Required (serializable)
530: */
531: private static final long serialVersionUID = 5061108355293832820L;
532:
533: public boolean isCellEditable(int rowIndex,
534: int columnIndex) {
535: return false;
536: }
537: };
538: packsTable.setModel(packsModel);
539: CheckBoxRenderer packSelectedRenderer = new CheckBoxRenderer();
540: packsTable.getColumnModel().getColumn(0).setCellRenderer(
541: packSelectedRenderer);
542: packsTable.getColumnModel().getColumn(0).setMaxWidth(40);
543:
544: //packsTable.getColumnModel().getColumn(1).setCellRenderer(renderer1);
545: packsTable.getColumnModel().getColumn(1).setCellRenderer(
546: new PacksPanelTableCellRenderer());
547: PacksPanelTableCellRenderer renderer2 = new PacksPanelTableCellRenderer();
548: renderer2.setHorizontalAlignment(RIGHT);
549: packsTable.getColumnModel().getColumn(2).setCellRenderer(
550: renderer2);
551: packsTable.getColumnModel().getColumn(2).setMaxWidth(100);
552:
553: // remove header,so we don't need more strings
554: tableScroller.remove(packsTable.getTableHeader());
555: tableScroller.setColumnHeaderView(null);
556: tableScroller.setColumnHeader(null);
557:
558: // set the JCheckBoxes to the currently selected panels. The
559: // selection might have changed in another panel
560: java.util.Iterator iter = idata.availablePacks.iterator();
561: bytes = 0;
562: while (iter.hasNext()) {
563: Pack p = (Pack) iter.next();
564: if (p.required) {
565: bytes += p.nbytes;
566: continue;
567: }
568: if (idata.selectedPacks.contains(p))
569: bytes += p.nbytes;
570: }
571: } catch (Exception e) {
572: e.printStackTrace();
573: }
574:
575: showSpaceRequired();
576: showFreeSpace();
577: packsTable.setRowSelectionInterval(0, 0);
578: }
579:
580: /*
581: * (non-Javadoc)
582: *
583: * @see com.izforge.izpack.installer.IzPanel#getSummaryBody()
584: */
585: public String getSummaryBody() {
586: StringBuffer retval = new StringBuffer(256);
587: Iterator iter = idata.selectedPacks.iterator();
588: boolean first = true;
589: while (iter.hasNext()) {
590: if (!first) {
591: retval.append("<br>");
592: }
593: first = false;
594: Pack pack = (Pack) iter.next();
595: if (langpack != null && pack.id != null
596: && !"".equals(pack.id)) {
597: retval.append(langpack.getString(pack.id));
598: } else
599: retval.append(pack.name);
600: }
601: if (packsModel.isModifyinstallation()) {
602: Map installedpacks = packsModel.getInstalledpacks();
603: iter = installedpacks.keySet().iterator();
604: retval.append("<br><b>");
605: retval
606: .append(langpack
607: .getString("PacksPanel.installedpacks.summarycaption"));
608: retval.append("</b>");
609: retval.append("<br>");
610: while (iter.hasNext()) {
611: Pack pack = (Pack) installedpacks.get(iter.next());
612: if (langpack != null && pack.id != null
613: && !"".equals(pack.id)) {
614: retval.append(langpack.getString(pack.id));
615: } else {
616: retval.append(pack.name);
617: }
618: retval.append("<br>");
619: }
620: }
621: return (retval.toString());
622: }
623:
624: static class CheckBoxRenderer implements TableCellRenderer {
625: public Component getTableCellRendererComponent(JTable table,
626: Object value, boolean isSelected, boolean hasFocus,
627: int row, int column) {
628: JCheckBox display = new JCheckBox();
629: if (com.izforge.izpack.util.OsVersion.IS_UNIX
630: && !com.izforge.izpack.util.OsVersion.IS_OSX) {
631: display.setIcon(new LFIndependentIcon());
632: display.setDisabledIcon(new LFIndependentIcon());
633: display.setSelectedIcon(new LFIndependentIcon());
634: display
635: .setDisabledSelectedIcon(new LFIndependentIcon());
636: }
637: display.setHorizontalAlignment(CENTER);
638:
639: if (isSelected) {
640: display.setForeground(table.getSelectionForeground());
641: display.setBackground(table.getSelectionBackground());
642: } else {
643: display.setForeground(table.getForeground());
644: display.setBackground(table.getBackground());
645: }
646: int state = (Integer) value;
647: if (state == -2) {
648: // condition not fulfilled
649: display.setForeground(Color.GRAY);
650: }
651: display
652: .setSelected((value != null && Math.abs(state) == 1));
653:
654: if (state == -3) {
655: display.setForeground(Color.RED);
656: display.setSelected(true);
657: }
658:
659: display.setEnabled(state >= 0);
660: return display;
661: }
662: }
663:
664: public static class LFIndependentIcon implements Icon {
665: ButtonModel buttonModel = null;
666:
667: protected int getControlSize() {
668: return 13;
669: }
670:
671: public void paintIcon(Component c, Graphics g, int x, int y) {
672: ButtonModel model = ((JCheckBox) c).getModel();
673: buttonModel = model;
674: int controlSize = getControlSize();
675: if (model.isPressed() && model.isArmed()) {
676: g.setColor(MetalLookAndFeel.getControlShadow());
677: if (model.isEnabled())
678: g.setColor(Color.green);
679: else
680: g.setColor(Color.gray);
681: g.fillRect(x, y, controlSize - 1, controlSize - 1);
682: drawPressedBorder(g, x, y, controlSize, controlSize,
683: model);
684: } else {
685: drawBorder(g, x, y, controlSize, controlSize, model);
686: }
687: g.setColor(Color.green);
688: if (model.isSelected()) {
689: drawCheck(c, g, x, y);
690: }
691: }
692:
693: private void drawBorder(Graphics g, int x, int y, int w, int h,
694: ButtonModel model) {
695: g.translate(x, y);
696:
697: // outer frame rectangle
698: g.setColor(MetalLookAndFeel.getControlDarkShadow());
699: if (!model.isEnabled())
700: g.setColor(new Color(0.4f, 0.4f, 0.4f));
701: g.drawRect(0, 0, w - 2, h - 2);
702:
703: // middle frame
704: g.setColor(MetalLookAndFeel.getControlHighlight());
705: if (!model.isEnabled())
706: g.setColor(new Color(0.6f, 0.6f, 0.6f));
707: g.drawRect(1, 1, w - 2, h - 2);
708:
709: // background
710: if (model.isEnabled())
711: g.setColor(Color.white);
712: else
713: g.setColor(new Color(0.8f, 0.8f, 0.8f));
714: g.fillRect(2, 2, w - 3, h - 3);
715:
716: //some extra lines for FX
717: g.setColor(MetalLookAndFeel.getControl());
718: g.drawLine(0, h - 1, 1, h - 2);
719: g.drawLine(w - 1, 0, w - 2, 1);
720: g.translate(-x, -y);
721: }
722:
723: private void drawPressedBorder(Graphics g, int x, int y, int w,
724: int h, ButtonModel model) {
725: g.translate(x, y);
726: drawBorder(g, 0, 0, w, h, model);
727: g.setColor(MetalLookAndFeel.getControlShadow());
728: g.drawLine(1, 1, 1, h - 2);
729: g.drawLine(1, 1, w - 2, 1);
730: g.drawLine(2, 2, 2, h - 3);
731: g.drawLine(2, 2, w - 3, 2);
732: g.translate(-x, -y);
733: }
734:
735: protected void drawCheck(Component c, Graphics g, int x, int y) {
736: int controlSize = getControlSize();
737: if (buttonModel != null)
738: if (buttonModel.isEnabled())
739: g.setColor(new Color(0.0f, 0.6f, 0.0f));
740: else
741: g.setColor(new Color(0.1f, 0.1f, 0.1f));
742:
743: g.drawLine(x + (controlSize - 4), y + 2, x
744: + (controlSize - 4) - 4, y + 2 + 4);
745: g.drawLine(x + (controlSize - 4), y + 3, x
746: + (controlSize - 4) - 4, y + 3 + 4);
747: g.drawLine(x + (controlSize - 4), y + 4, x
748: + (controlSize - 4) - 4, y + 4 + 4);
749:
750: g.drawLine(x + (controlSize - 4) - 4, y + 2 + 4, x
751: + (controlSize - 4) - 4 - 2, y + 2 + 4 - 2);
752: g.drawLine(x + (controlSize - 4) - 4, y + 3 + 4, x
753: + (controlSize - 4) - 4 - 2, y + 3 + 4 - 2);
754: g.drawLine(x + (controlSize - 4) - 4, y + 4 + 4, x
755: + (controlSize - 4) - 4 - 2, y + 4 + 4 - 2);
756: }
757:
758: public int getIconWidth() {
759: return getControlSize();
760: }
761:
762: public int getIconHeight() {
763: return getControlSize();
764: }
765: }
766:
767: static class PacksPanelTableCellRenderer extends
768: DefaultTableCellRenderer {
769:
770: /**
771: * Required (serializable)
772: */
773: private static final long serialVersionUID = -9089892183236584242L;
774:
775: public Component getTableCellRendererComponent(JTable table,
776: Object value, boolean isSelected, boolean hasFocus,
777: int row, int column) {
778: Component renderer = super .getTableCellRendererComponent(
779: table, value, isSelected, hasFocus, row, column);
780:
781: int state = (Integer) table.getModel().getValueAt(row, 0);
782: if (state == -2) {
783: // condition not fulfilled
784: renderer.setForeground(Color.GRAY);
785: if (isSelected) {
786: renderer.setBackground(table
787: .getSelectionBackground());
788: } else {
789: renderer.setBackground(table.getBackground());
790: }
791: } else {
792: if (isSelected) {
793: renderer.setForeground(table
794: .getSelectionForeground());
795: renderer.setBackground(table
796: .getSelectionBackground());
797: } else {
798: renderer.setForeground(table.getForeground());
799: renderer.setBackground(table.getBackground());
800: }
801: }
802:
803: return renderer;
804: }
805:
806: }
807:
808: public Debugger getDebugger() {
809: return this.debugger;
810: }
811: }
|