001: /*
002: * This file is part of the GeOxygene project source files.
003: *
004: * GeOxygene aims at providing an open framework which implements OGC/ISO specifications for
005: * the development and deployment of geographic (GIS) applications. It is a open source
006: * contribution of the COGIT laboratory at the Institut Géographique National (the French
007: * National Mapping Agency).
008: *
009: * See: http://oxygene-project.sourceforge.net
010: *
011: * Copyright (C) 2005 Institut Géographique National
012: *
013: * This library is free software; you can redistribute it and/or modify it under the terms
014: * of the GNU Lesser General Public License as published by the Free Software Foundation;
015: * either version 2.1 of the License, or any later version.
016: *
017: * This library is distributed in the hope that it will be useful, but WITHOUT ANY
018: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
019: * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
020: *
021: * You should have received a copy of the GNU Lesser General Public License along with
022: * this library (see file LICENSE if present); if not, write to the Free Software
023: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024: *
025: */
026:
027: package fr.ign.cogit.geoxygene.util.browser;
028:
029: import java.awt.Color;
030: import java.awt.Dimension;
031: import java.awt.Font;
032: import java.awt.GridBagConstraints;
033: import java.awt.GridBagLayout;
034: import java.awt.GridLayout;
035: import java.awt.Insets;
036: import java.awt.event.ActionEvent;
037: import java.awt.event.ActionListener;
038: import java.lang.reflect.Method;
039: import java.text.MessageFormat;
040: import java.util.Locale;
041: import java.util.ResourceBundle;
042: import java.util.Vector;
043:
044: import javax.swing.JButton;
045: import javax.swing.JFrame;
046: import javax.swing.JLabel;
047: import javax.swing.JMenu;
048: import javax.swing.JMenuBar;
049: import javax.swing.JMenuItem;
050: import javax.swing.JPanel;
051: import javax.swing.JScrollPane;
052: import javax.swing.JTextField;
053:
054: /**
055: * Cette classe met en oeuvre l'interface graphique (vue et contrôleur) du Navigateur d'objet de GeOxygene, conformement à
056: * l'architecture à modèle séparable de Sun Microsystems.
057: * Les méthodes mises à disposition par cette classe sont appelées depuis la classe ObjectBrowser (modèle).
058: *
059: * @author Thierry Badard & Arnaud Braun
060: * @version 1.0
061: *
062: */
063:
064: public class ObjectBrowserGUI extends JFrame {
065: /** Localisation des fichiers d'internationalisation de l'interface. */
066: private static final String I18N_LANGUAGE_FILE_LOCATION = "fr.ign.cogit.geoxygene.util.browser.ObjectBrowserLanguageFile";
067: /** Nombre de lignes visibles dans l'interface pour les attributs de type tableau ou Collection. */
068: private static final int NBVISIBLEROW = 3;
069:
070: /** Gestionnaire de contraintes de mise en page du navigateur d'objet. */
071: public GridBagConstraints gbc = new GridBagConstraints();
072: /** Gestionnaire de mise en page du navigateur d'objet. */
073: public GridBagLayout gbl = new GridBagLayout();
074: /** Insets définissant l'espacement entre les différents composants graphiques de l'interface. */
075: public Insets extpad = new Insets(2, 5, 2, 5);
076: /** Panel d'affichage dans lequel sont positionnés les éléments. */
077: public JPanel panel = new JPanel();
078: public GridLayout gl_panel = new GridLayout();
079: public int ncc;
080:
081: /** L'objet dont l'interface courante du navigateur d'objet de GeOxygene est la représentation. */
082: private Object browsedObject;
083:
084: /** Flag définissant si l'affichage d'un bandeau contenant le nom du type de l'objet a été demandé par le modèle (ObjectBrowser). */
085: private boolean showClassName;
086: /** Flag définissant si l'affichage des attributs publics de l'objet a été demandé par le modèle (ObjectBrowser). */
087: private boolean showPublicAttributes;
088: /** Flag définissant si l'affichage des attributs protected de l'objet a été demandé par le modèle (ObjectBrowser). */
089: private boolean showProtectedAttributes;
090: /** Flag définissant si l'affichage des méthodes publiques, locales et héritées de l'objet a été demandé par le modèle (ObjectBrowser). */
091: private boolean showPublicMethods;
092: /** Flag définissant si l'affichage des méthodes protected, locales et héritées de l'objet a été demandé par le modèle (ObjectBrowser). */
093: private boolean showProtectedMethods;
094:
095: /** Locale courante. */
096: private Locale currentLocale;
097: /** RessourceBundle lié à la Locale et au fichier d'internationalisation. */
098: private ResourceBundle i18nLanguageFile;
099:
100: /**
101: * Constructeur par défaut.
102: *
103: * @param browsedObject l'objet que l'interface du navigateur que l'on cherche à construire doit représenter.
104: * @param showClassName l'affichage d'un bandeau comportant le nom du type de l'objet est-il demandé ?
105: * @param showPublicAttributes l'affichage des attributs publics de l'objet est-il demandé ?
106: * @param showProtectedAttributes l'affichage des attributs protected de l'objet est-il demandé ?
107: * @param showPublicMethods l'affichage des méthodes publiques, locales et héritées de l'objet est-il demandé ?
108: * @param showProtectedMethods l'affichage des méthodes protected, locales et héritées de l'objet est-il demandé ?
109: */
110: public ObjectBrowserGUI(Object browsedObject,
111: boolean showClassName, boolean showPublicAttributes,
112: boolean showProtectedAttributes, boolean showPublicMethods,
113: boolean showProtectedMethods) {
114: super ();
115: currentLocale = Locale.getDefault();
116: i18nLanguageFile = ResourceBundle.getBundle(
117: I18N_LANGUAGE_FILE_LOCATION, currentLocale);
118: //i18nLanguageFile = ResourceBundle.getBundle(I18N_LANGUAGE_FILE_LOCATION,new Locale("en", "US"));
119:
120: setTitle(i18nLanguageFile.getString("DefaultFrameTitle"));
121: this .browsedObject = browsedObject;
122: this .showClassName = showClassName;
123: this .showPublicAttributes = showPublicAttributes;
124: this .showProtectedAttributes = showProtectedAttributes;
125: this .showPublicMethods = showPublicMethods;
126: this .showProtectedMethods = showProtectedMethods;
127: initInterface();
128: }
129:
130: /**
131: * Construit une instance du navigateur d'objet de GeOxygene pour l'objet browsedObject avec un titre de fenêtre faisant référence à className.
132: *
133: * @param browsedObject l'objet que l'interface du navigateur que l'on cherche à construire doit représenter.
134: * @param showClassName l'affichage d'un bandeau comportant le nom du type de l'objet est-il demandé ?
135: * @param showPublicAttributes l'affichage des attributs publics de l'objet est-il demandé ?
136: * @param showProtectedAttributes l'affichage des attributs protected de l'objet est-il demandé ?
137: * @param showPublicMethods l'affichage des méthodes publiques, locales et héritées de l'objet est-il demandé ?
138: * @param showProtectedMethods l'affichage des méthodes protected, locales et héritées de l'objet est-il demandé ?
139: * @param className le nom du type de l'objet représenté par l'interface du navigateur que l'on cherche à construire.
140: */
141: public ObjectBrowserGUI(Object browsedObject,
142: boolean showClassName, boolean showPublicAttributes,
143: boolean showProtectedAttributes, boolean showPublicMethods,
144: boolean showProtectedMethods, String className) {
145: super ();
146: currentLocale = Locale.getDefault();
147: i18nLanguageFile = ResourceBundle.getBundle(
148: I18N_LANGUAGE_FILE_LOCATION, currentLocale);
149: //i18nLanguageFile = ResourceBundle.getBundle(I18N_LANGUAGE_FILE_LOCATION,new Locale("en", "US"));
150:
151: setTitle(i18nLanguageFile.getString("DefaultFrameTitle") + " "
152: + className);
153: this .browsedObject = browsedObject;
154: this .showClassName = showClassName;
155: this .showPublicAttributes = showPublicAttributes;
156: this .showProtectedAttributes = showProtectedAttributes;
157: this .showPublicMethods = showPublicMethods;
158: this .showProtectedMethods = showProtectedMethods;
159: initInterface();
160: }
161:
162: /**
163: * Méthode permettant le changement du titre de la fenêtre d'interface représentant l'objet courant.
164: *
165: * @param className le nom du type de l'objet représenté par l'interface du navigateur d'objet.
166: */
167: protected void changeTitle(String className) {
168: setTitle(i18nLanguageFile.getString("DefaultFrameTitle") + " "
169: + className);
170: }
171:
172: /**
173: * Initialisation de l'interface graphique du navgateur d'objet.
174: */
175: private void initInterface() {
176:
177: this .ncc = 0;
178: this .getContentPane().setLayout(this .gl_panel);
179: this .panel.setLayout(this .gbl);
180:
181: JScrollPane scrolling_panel = new JScrollPane(this .panel);
182: JMenuBar jmb = new JMenuBar();
183:
184: // Definition of the "File" menu and of the "Close" attached item.
185:
186: JMenu file = new JMenu(i18nLanguageFile
187: .getString("MenuFileLabel"));
188: JMenuItem item;
189: file.add(item = new JMenuItem(i18nLanguageFile
190: .getString("MenuFileCloseItemLabel")));
191: item.addActionListener(new ActionListener() {
192: public void actionPerformed(ActionEvent e) {
193: dispose();
194: }
195: });
196:
197: // Definition of the "Exit" item.
198:
199: file.addSeparator();
200: file.add(item = new JMenuItem(i18nLanguageFile
201: .getString("MenuFileExitItemLabel")));
202: item.addActionListener(new ActionListener() {
203: public void actionPerformed(ActionEvent e) {
204: dispose();
205: System.exit(0);
206: }
207: });
208: jmb.add(file);
209:
210: // Definition of the "Edit" menu and of the "Refresh" attached item.
211:
212: JMenu edit = new JMenu(i18nLanguageFile
213: .getString("MenuEditLabel"));
214: edit.add(item = new JMenuItem(i18nLanguageFile
215: .getString("MenuEditRefreshItemLabel")));
216: item.addActionListener(new ActionListener() {
217: public void actionPerformed(ActionEvent e) {
218: ObjectBrowser.refresh(getBrowsedObject(),
219: ObjectBrowser.HIDE_WHEN_REFRESH, showClassName,
220: showPublicAttributes, showProtectedAttributes,
221: showPublicMethods, showProtectedMethods);
222: }
223: });
224: jmb.add(edit);
225:
226: this .setJMenuBar(jmb);
227:
228: this .getContentPane().add(scrolling_panel);
229: }
230:
231: /**
232: * Ajoute un bandeau à l'interface contenant l'affichage du type (className) de l'objet représenté
233: * par l'instance courante du navigateur d'objet.
234: *
235: * @param className le type de l'objet représenté par l'instance courante du navigateur d'objet.
236: */
237: public void addClassNameLabel(String className) {
238: JLabel label = new JLabel(className, JLabel.CENTER);
239: label.setOpaque(true);
240: label.setBackground(Color.GRAY);
241:
242: label.setFont(new Font("SansSerif", Font.BOLD, 16));
243:
244: this .gbc.fill = GridBagConstraints.BOTH;
245: this .gbc.gridy = this .ncc;
246: this .gbc.gridwidth = 2;
247: this .gbc.gridheight = 1;
248: this .gbc.insets = this .extpad;
249:
250: this .gbc.gridx = 0;
251: this .gbc.weightx = 25;
252: this .gbl.setConstraints(label, gbc);
253: this .panel.add(label);
254:
255: this .ncc++;
256: }
257:
258: /**
259: * Ajoute à l'interface du navigateur, la représentation d'un attribut de type primitif ou chaîne de caractères.
260: *
261: * @param attrib_label le nom de l'attribut.
262: * @param attrib_value la valeur de l'attribut.
263: */
264: public void addAttribute(String attrib_label, String attrib_value) {
265: JLabel label = new JLabel(attrib_label + " :", JLabel.RIGHT);
266: JTextField txtfld = new JTextField(attrib_value);
267:
268: this .gbc.fill = GridBagConstraints.BOTH;
269: this .gbc.gridy = this .ncc;
270: this .gbc.gridwidth = 1;
271: this .gbc.gridheight = 1;
272: this .gbc.insets = this .extpad;
273:
274: this .gbc.gridx = 0;
275: this .gbc.weightx = 25;
276: this .gbl.setConstraints(label, gbc);
277: this .panel.add(label);
278:
279: this .gbc.gridx = 1;
280: this .gbc.weightx = 75;
281: this .gbl.setConstraints(txtfld, gbc);
282: this .panel.add(txtfld);
283:
284: this .ncc++;
285: }
286:
287: /**
288: * Ajoute à l'interface du navigateur, la représentation d'un attribut de type objet.
289: *
290: * @param attrib_label le nom de l'attribut.
291: * @param attrib_type le type de l'attribut.
292: * @param attrib_obj la valeur de l'attribut.
293: */
294: public void addObjectAttribute(String attrib_label,
295: String attrib_type, Object attrib_obj) {
296: JLabel label = new JLabel(attrib_label + " :", JLabel.RIGHT);
297: JButton object_button = new JButton(attrib_type);
298: object_button.setToolTipText("Visualiser l'objet de type "
299: + attrib_type + ".");
300: object_button
301: .addActionListener(new ObjectBrowserAttributeListener(
302: attrib_obj));
303:
304: this .gbc.fill = GridBagConstraints.BOTH;
305: this .gbc.gridy = this .ncc;
306: this .gbc.gridwidth = 1;
307: this .gbc.gridheight = 1;
308: this .gbc.insets = this .extpad;
309:
310: this .gbc.gridx = 0;
311: this .gbc.weightx = 25;
312: this .gbl.setConstraints(label, gbc);
313: this .panel.add(label);
314:
315: this .gbc.gridx = 1;
316: this .gbc.weightx = 75;
317: this .gbl.setConstraints(object_button, gbc);
318: this .panel.add(object_button);
319:
320: this .ncc++;
321: }
322:
323: /**
324: * Ajoute à l'interface du navigateur, un composant graphique représentant le contenu d'un tableau ou d'une
325: * collection de type primitif ou chaîne de caractères.
326: * <p>ATTENTION: méthode vouée à disparaître, car remplacée par addObjectAttributeList() !</p>
327: * @param attrib_values un vecteur contenant l'ensemble des valeurs de l'objet de type tableau ou collection.
328: */
329: public void addAttributeList(Vector attrib_values) {
330: //addAttributeList(i18nLanguageFile.getString("DefaultCollectionClassesContentLabel"),attrib_values);
331: addObjectAttributeList(i18nLanguageFile
332: .getString("DefaultCollectionClassesContentLabel"),
333: attrib_values);
334: }
335:
336: /**
337: * Ajoute à l'interface du navigateur, un composant graphique représentant le contenu d'un attribut de type tableau ou
338: * collection de type primitif ou chaîne de caractères.
339: * <p>ATTENTION: méthode vouée à disparaître, car remplacée par addObjectAttributeList() !</p>
340: * @param attrib_label le nom de l'attribut.
341: * @param attrib_values les valeurs du tableau ou de la collection portés par l'attribut.
342: */
343: public void addAttributeList(String attrib_label,
344: Vector attrib_values) {
345:
346: addObjectAttributeList(attrib_label, attrib_values);
347:
348: /* JLabel label = new JLabel(attrib_label + " :", JLabel.RIGHT);
349: JList attribList = new JList(attrib_values);
350: attribList.setVisibleRowCount(NBVISIBLEROW);
351: attribList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
352: JScrollPane attribPane = new JScrollPane(attribList);
353:
354: this.gbc.fill = GridBagConstraints.BOTH;
355: this.gbc.gridy = this.ncc;
356: this.gbc.gridwidth = 1;
357: this.gbc.gridheight = 1;
358: this.gbc.insets = this.extpad;
359:
360: this.gbc.gridx = 0;
361: this.gbc.weightx = 25;
362: this.gbl.setConstraints(label, gbc);
363: this.panel.add(label);
364:
365: this.gbc.gridx = 1;
366: this.gbc.weightx = 75;
367: this.gbl.setConstraints(attribPane, gbc);
368: this.panel.add(attribPane);
369:
370: this.ncc++; */
371: }
372:
373: /**
374: * Ajoute à l'interface du navigateur, un composant graphique représentant le contenu d'un tableau ou d'une
375: * collection.
376: * @param attrib_objects un vecteur contenant l'ensemble des valeurs de l'objet de type tableau ou collection.
377: */
378: public void addObjectAttributeList(Vector attrib_objects) {
379: addObjectAttributeList(i18nLanguageFile
380: .getString("DefaultCollectionClassesContentLabel"),
381: attrib_objects, 1, "");
382: }
383:
384: /**
385: * Ajoute à l'interface du navigateur, un composant graphique représentant le contenu d'un attribut de type tableau ou
386: * collection.
387: * @param attrib_label le nom de l'attribut.
388: * @param attrib_objects les valeurs du tableau ou de la collection portés par l'attribut.
389: */
390: public void addObjectAttributeList(String attrib_label,
391: Vector attrib_objects) {
392: addObjectAttributeList(attrib_label, attrib_objects, 1, "");
393: }
394:
395: /**
396: * Ajoute à l'interface du navigateur, un composant graphique représentant le contenu d'un attribut de type tableau ou
397: * collection.
398: * @param attrib_label le nom de l'attribut.
399: * @param attrib_objects les valeurs du tableau ou de la collection portés par l'attribut.
400: * @param attrib_level la dimension du tableau ou de la collection.
401: * @param attrib_underlyingType le type du contenu du tableau ou de la collection.
402: */
403: public void addObjectAttributeList(String attrib_label,
404: Vector attrib_objects, int attrib_level,
405: String attrib_underlyingType) {
406: JLabel label = new JLabel(attrib_label + " :", JLabel.RIGHT);
407: JPanel attribListPanel = new JPanel();
408: int NbElemAttribList = attrib_objects.size();
409: GridLayout gl_attribListPanel = new GridLayout(
410: NbElemAttribList, 1);
411: //GridLayout gl_attribListPanel = new GridLayout(NbElemAttribList,2);
412: attribListPanel.setLayout(gl_attribListPanel);
413: String attribTypeName;
414: Class attribType;
415: String attribValue;
416: double prefHeight = 0;
417: double prefWidth = 0;
418: double prefWidthMax = 0;
419: boolean isTextPrintableField = false;
420:
421: for (int i = 0; i < NbElemAttribList; i++) {
422: //JLabel listlabel = new JLabel(i+":",JLabel.RIGHT);
423: //attribListPanel.add(listlabel);
424:
425: attribType = attrib_objects.get(i).getClass();
426: attribValue = attrib_objects.get(i).toString();
427: isTextPrintableField = false;
428:
429: if (attrib_underlyingType.equals("")) {
430: attribTypeName = attribType.getName();
431: } else {
432: attribTypeName = "";
433: for (int j = 0; j < attrib_level; j++) {
434: attribTypeName += "[";
435: }
436: attribTypeName += attrib_underlyingType;
437: for (int j = 0; j < attrib_level; j++) {
438: attribTypeName += "]";
439: }
440: }
441:
442: if (attribTypeName.equals("java.lang.String")
443: || attribTypeName.equals("java.lang.Boolean")
444: || attribTypeName.equals("java.lang.Byte")
445: || attribTypeName.equals("java.lang.Character")
446: || attribTypeName.equals("java.lang.Double")
447: || attribTypeName.equals("java.lang.Float")
448: || attribTypeName.equals("java.lang.Integer")
449: || attribTypeName.equals("java.lang.Long")
450: || attribTypeName.equals("java.lang.Short")) {
451: isTextPrintableField = true;
452: }
453:
454: //if (!((attribValue.indexOf("@") > -1) || (attribValue.lastIndexOf("[") > -1))) {
455: if (isTextPrintableField) {
456: JTextField txtfld = new JTextField(attribValue);
457: attribListPanel.add(txtfld);
458: if (i < NBVISIBLEROW) {
459: //prefsize += 7 + txtfld.getPreferredSize().getHeight();
460: prefHeight += txtfld.getPreferredSize().getHeight();
461: }
462: prefWidth = txtfld.getPreferredSize().getWidth();
463: if (prefWidth > prefWidthMax)
464: prefWidthMax = prefWidth;
465: } else {
466: JButton object_button = new JButton(attribTypeName);
467:
468: Object[] msgArguments = { new Integer(i),
469: attribTypeName };
470: MessageFormat formatter = new MessageFormat("");
471: formatter.setLocale(currentLocale);
472: formatter.applyPattern(i18nLanguageFile
473: .getString("AttributeToolTipLabel"));
474: object_button.setToolTipText(formatter
475: .format(msgArguments));
476:
477: object_button
478: .addActionListener(new ObjectBrowserAttributeListener(
479: attrib_objects.get(i)));
480: attribListPanel.add(object_button);
481: if (i < NBVISIBLEROW) {
482: prefHeight += 1 + object_button.getPreferredSize()
483: .getHeight();
484: //prefsize += object_button.getPreferredSize().getHeight();
485: }
486: prefWidth = object_button.getPreferredSize().getWidth();
487: if (prefWidth > prefWidthMax)
488: prefWidthMax = prefWidth;
489: }
490: }
491:
492: JScrollPane attribPane = new JScrollPane(attribListPanel);
493:
494: //attribPane.setPreferredSize(new Dimension(100, (int) prefsize));
495: attribPane.setPreferredSize(new Dimension(
496: (int) (prefWidthMax + 50), (int) (prefHeight + 3)));
497:
498: ObjectBrowserListRuler lruler = new ObjectBrowserListRuler(
499: NbElemAttribList, (int) attribListPanel
500: .getPreferredSize().getHeight());
501: lruler.setPreferredHeight((int) (attribListPanel
502: .getPreferredSize().getHeight()));
503: attribPane.setRowHeaderView(lruler);
504:
505: //attribPane.setPreferredSize(new Dimension(0, (int) prefsize));
506: //attribPane.setPreferredSize(new Dimension((int) (prefwidthmax*1.2), (int) prefsize));
507:
508: this .gbc.fill = GridBagConstraints.BOTH;
509: this .gbc.gridy = this .ncc;
510: this .gbc.gridwidth = 1;
511: this .gbc.gridheight = 1;
512: this .gbc.insets = this .extpad;
513:
514: this .gbc.gridx = 0;
515: this .gbc.weightx = 25;
516: this .gbl.setConstraints(label, gbc);
517: this .panel.add(label);
518:
519: this .gbc.gridx = 1;
520: this .gbc.weightx = 75;
521: this .gbl.setConstraints(attribPane, gbc);
522: this .panel.add(attribPane);
523:
524: this .ncc++;
525: }
526:
527: /**
528: * Ajoute à l'interface du navigateur, un composant graphique représentant une méthode.
529: *
530: * @param obj l'objet portant la méthode à représenter au sein de l'interface du navigateur d'objet de GeOxygene.
531: * @param method la méthde qui doit être représenté par ce composant graphique.
532: */
533: public void addMethod(Object obj, Method method) {
534: JButton method_button = new JButton(method.getName());
535:
536: Object[] msgArguments = { method.getName() };
537: MessageFormat formatter = new MessageFormat("");
538: formatter.setLocale(currentLocale);
539: formatter.applyPattern(i18nLanguageFile
540: .getString("MethodToolTipLabel"));
541: method_button.setToolTipText(formatter.format(msgArguments));
542:
543: method_button
544: .addActionListener(new ObjectBrowserMethodListener(obj,
545: method));
546:
547: this .gbc.fill = GridBagConstraints.BOTH;
548: this .gbc.gridy = this .ncc;
549: this .gbc.gridwidth = 2;
550: this .gbc.gridheight = 1;
551: this .gbc.insets = this .extpad;
552:
553: this .gbc.gridx = 0;
554: this .gbc.weightx = 100;
555: this .gbl.setConstraints(method_button, gbc);
556: this .panel.add(method_button);
557:
558: this .ncc++;
559: }
560:
561: /**
562: * @return l'objet dont l'interface courante du navigateur d'objet de GeOxygene est la représentation.
563: */
564: public Object getBrowsedObject() {
565: return this .browsedObject;
566: }
567:
568: /**
569: * @return le RessourceBundle lié à la Locale et au fichier d'internationalisation.
570: */
571: public ResourceBundle getI18nLanguageFile() {
572: return i18nLanguageFile;
573: }
574:
575: }
|