History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/JMenuBar.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/JMenuBar.java+765−0
@@ -0,0 +1,765 @@
1+/*
2+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package javax.swing;
27+
28+import java.awt.Component;
29+import java.awt.Dimension;
30+import java.awt.Graphics;
31+import java.awt.Insets;
32+import java.awt.Point;
33+import java.awt.Rectangle;
34+import java.awt.event.*;
35+import java.beans.Transient;
36+import java.util.Vector;
37+import java.util.Enumeration;
38+
39+import java.io.Serializable;
40+import java.io.ObjectOutputStream;
41+import java.io.ObjectInputStream;
42+import java.io.IOException;
43+
44+import javax.swing.event.*;
45+import javax.swing.border.Border;
46+import javax.swing.plaf.*;
47+import javax.accessibility.*;
48+
49+/**
50+ * An implementation of a menu bar. You add <code>JMenu</code> objects to the
51+ * menu bar to construct a menu. When the user selects a <code>JMenu</code>
52+ * object, its associated <code>JPopupMenu</code> is displayed, allowing the
53+ * user to select one of the <code>JMenuItems</code> on it.
54+ * <p>
55+ * For information and examples of using menu bars see
56+ * <a
57+ href="http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
58+ * a section in <em>The Java Tutorial.</em>
59+ * <p>
60+ * <strong>Warning:</strong> Swing is not thread safe. For more
61+ * information see <a
62+ * href="package-summary.html#threading">Swing's Threading
63+ * Policy</a>.
64+ * <p>
65+ * <strong>Warning:</strong>
66+ * Serialized objects of this class will not be compatible with
67+ * future Swing releases. The current serialization support is
68+ * appropriate for short term storage or RMI between applications running
69+ * the same version of Swing. As of 1.4, support for long term storage
70+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
71+ * has been added to the <code>java.beans</code> package.
72+ * Please see {@link java.beans.XMLEncoder}.
73+ *
74+ * @beaninfo
75+ * attribute: isContainer true
76+ * description: A container for holding and displaying menus.
77+ *
78+ * @author Georges Saab
79+ * @author David Karlton
80+ * @author Arnaud Weber
81+ * @see JMenu
82+ * @see JPopupMenu
83+ * @see JMenuItem
84+ */
85+public class JMenuBar extends JComponent implements Accessible,MenuElement
86+{
87+ /**
88+ * @see #getUIClassID
89+ * @see #readObject
90+ */
91+ private static final String uiClassID = "MenuBarUI";
92+
93+ /*
94+ * Model for the selected subcontrol.
95+ */
96+ private transient SingleSelectionModel selectionModel;
97+
98+ private boolean paintBorder = true;
99+ private Insets margin = null;
100+
101+ /* diagnostic aids -- should be false for production builds. */
102+ private static final boolean TRACE = false; // trace creates and disposes
103+ private static final boolean VERBOSE = false; // show reuse hits/misses
104+ private static final boolean DEBUG = false; // show bad params, misc.
105+
106+ /**
107+ * Creates a new menu bar.
108+ */
109+ public JMenuBar() {
110+ super();
111+ setFocusTraversalKeysEnabled(false);
112+ setSelectionModel(new DefaultSingleSelectionModel());
113+ updateUI();
114+ }
115+
116+ /**
117+ * Returns the menubar's current UI.
118+ * @see #setUI
119+ */
120+ public MenuBarUI getUI() {
121+ return (MenuBarUI)ui;
122+ }
123+
124+ /**
125+ * Sets the L&F object that renders this component.
126+ *
127+ * @param ui the new MenuBarUI L&F object
128+ * @see UIDefaults#getUI
129+ * @beaninfo
130+ * bound: true
131+ * hidden: true
132+ * attribute: visualUpdate true
133+ * description: The UI object that implements the Component's LookAndFeel.
134+ */
135+ public void setUI(MenuBarUI ui) {
136+ super.setUI(ui);
137+ }
138+
139+ /**
140+ * Resets the UI property with a value from the current look and feel.
141+ *
142+ * @see JComponent#updateUI
143+ */
144+ public void updateUI() {
145+ setUI((MenuBarUI)UIManager.getUI(this));
146+ }
147+
148+
149+ /**
150+ * Returns the name of the L&F class that renders this component.
151+ *
152+ * @return the string "MenuBarUI"
153+ * @see JComponent#getUIClassID
154+ * @see UIDefaults#getUI
155+ */
156+ public String getUIClassID() {
157+ return uiClassID;
158+ }
159+
160+
161+ /**
162+ * Returns the model object that handles single selections.
163+ *
164+ * @return the <code>SingleSelectionModel</code> property
165+ * @see SingleSelectionModel
166+ */
167+ public SingleSelectionModel getSelectionModel() {
168+ return selectionModel;
169+ }
170+
171+ /**
172+ * Sets the model object to handle single selections.
173+ *
174+ * @param model the <code>SingleSelectionModel</code> to use
175+ * @see SingleSelectionModel
176+ * @beaninfo
177+ * bound: true
178+ * description: The selection model, recording which child is selected.
179+ */
180+ public void setSelectionModel(SingleSelectionModel model) {
181+ SingleSelectionModel oldValue = selectionModel;
182+ this.selectionModel = model;
183+ firePropertyChange("selectionModel", oldValue, selectionModel);
184+ }
185+
186+
187+ /**
188+ * Appends the specified menu to the end of the menu bar.
189+ *
190+ * @param c the <code>JMenu</code> component to add
191+ * @return the menu component
192+ */
193+ public JMenu add(JMenu c) {
194+ super.add(c);
195+ return c;
196+ }
197+
198+ /**
199+ * Returns the menu at the specified position in the menu bar.
200+ *
201+ * @param index an integer giving the position in the menu bar, where
202+ * 0 is the first position
203+ * @return the <code>JMenu</code> at that position, or <code>null</code> if
204+ * if there is no <code>JMenu</code> at that position (ie. if
205+ * it is a <code>JMenuItem</code>)
206+ */
207+ public JMenu getMenu(int index) {
208+ Component c = getComponentAtIndex(index);
209+ if (c instanceof JMenu)
210+ return (JMenu) c;
211+ return null;
212+ }
213+
214+ /**
215+ * Returns the number of items in the menu bar.
216+ *
217+ * @return the number of items in the menu bar
218+ */
219+ public int getMenuCount() {
220+ return getComponentCount();
221+ }
222+
223+ /**
224+ * Sets the help menu that appears when the user selects the
225+ * "help" option in the menu bar. This method is not yet implemented
226+ * and will throw an exception.
227+ *
228+ * @param menu the JMenu that delivers help to the user
229+ */
230+ public void setHelpMenu(JMenu menu) {
231+ throw new Error("setHelpMenu() not yet implemented.");
232+ }
233+
234+ /**
235+ * Gets the help menu for the menu bar. This method is not yet
236+ * implemented and will throw an exception.
237+ *
238+ * @return the <code>JMenu</code> that delivers help to the user
239+ */
240+ @Transient
241+ public JMenu getHelpMenu() {
242+ throw new Error("getHelpMenu() not yet implemented.");
243+ }
244+
245+ /**
246+ * Returns the component at the specified index.
247+ *
248+ * @param i an integer specifying the position, where 0 is first
249+ * @return the <code>Component</code> at the position,
250+ * or <code>null</code> for an invalid index
251+ * @deprecated replaced by <code>getComponent(int i)</code>
252+ */
253+ @Deprecated
254+ public Component getComponentAtIndex(int i) {
255+ if(i < 0 || i >= getComponentCount()) {
256+ return null;
257+ }
258+ return getComponent(i);
259+ }
260+
261+ /**
262+ * Returns the index of the specified component.
263+ *
264+ * @param c the <code>Component</code> to find
265+ * @return an integer giving the component's position, where 0 is first;
266+ * or -1 if it can't be found
267+ */
268+ public int getComponentIndex(Component c) {
269+ int ncomponents = this.getComponentCount();
270+ Component[] component = this.getComponents();
271+ for (int i = 0 ; i < ncomponents ; i++) {
272+ Component comp = component[i];
273+ if (comp == c)
274+ return i;
275+ }
276+ return -1;
277+ }
278+
279+ /**
280+ * Sets the currently selected component, producing a
281+ * a change to the selection model.
282+ *
283+ * @param sel the <code>Component</code> to select
284+ */
285+ public void setSelected(Component sel) {
286+ SingleSelectionModel model = getSelectionModel();
287+ int index = getComponentIndex(sel);
288+ model.setSelectedIndex(index);
289+ }
290+
291+ /**
292+ * Returns true if the menu bar currently has a component selected.
293+ *
294+ * @return true if a selection has been made, else false
295+ */
296+ public boolean isSelected() {
297+ return selectionModel.isSelected();
298+ }
299+
300+ /**
301+ * Returns true if the menu bars border should be painted.
302+ *
303+ * @return true if the border should be painted, else false
304+ */
305+ public boolean isBorderPainted() {
306+ return paintBorder;
307+ }
308+
309+ /**
310+ * Sets whether the border should be painted.
311+ *
312+ * @param b if true and border property is not <code>null</code>,
313+ * the border is painted.
314+ * @see #isBorderPainted
315+ * @beaninfo
316+ * bound: true
317+ * attribute: visualUpdate true
318+ * description: Whether the border should be painted.
319+ */
320+ public void setBorderPainted(boolean b) {
321+ boolean oldValue = paintBorder;
322+ paintBorder = b;
323+ firePropertyChange("borderPainted", oldValue, paintBorder);
324+ if (b != oldValue) {
325+ revalidate();
326+ repaint();
327+ }
328+ }
329+
330+ /**
331+ * Paints the menubar's border if <code>BorderPainted</code>
332+ * property is true.
333+ *
334+ * @param g the <code>Graphics</code> context to use for painting
335+ * @see JComponent#paint
336+ * @see JComponent#setBorder
337+ */
338+ protected void paintBorder(Graphics g) {
339+ if (isBorderPainted()) {
340+ super.paintBorder(g);
341+ }
342+ }
343+
344+ /**
345+ * Sets the margin between the menubar's border and
346+ * its menus. Setting to <code>null</code> will cause the menubar to
347+ * use the default margins.
348+ *
349+ * @param m an Insets object containing the margin values
350+ * @see Insets
351+ * @beaninfo
352+ * bound: true
353+ * attribute: visualUpdate true
354+ * description: The space between the menubar's border and its contents
355+ */
356+ public void setMargin(Insets m) {
357+ Insets old = margin;
358+ this.margin = m;
359+ firePropertyChange("margin", old, m);
360+ if (old == null || !old.equals(m)) {
361+ revalidate();
362+ repaint();
363+ }
364+ }
365+
366+ /**
367+ * Returns the margin between the menubar's border and
368+ * its menus. If there is no previous margin, it will create
369+ * a default margin with zero size.
370+ *
371+ * @return an <code>Insets</code> object containing the margin values
372+ * @see Insets
373+ */
374+ public Insets getMargin() {
375+ if(margin == null) {
376+ return new Insets(0,0,0,0);
377+ } else {
378+ return margin;
379+ }
380+ }
381+
382+
383+ /**
384+ * Implemented to be a <code>MenuElement</code> -- does nothing.
385+ *
386+ * @see #getSubElements
387+ */
388+ public void processMouseEvent(MouseEvent event,MenuElement path[],MenuSelectionManager manager) {
389+ }
390+
391+ /**
392+ * Implemented to be a <code>MenuElement</code> -- does nothing.
393+ *
394+ * @see #getSubElements
395+ */
396+ public void processKeyEvent(KeyEvent e,MenuElement path[],MenuSelectionManager manager) {
397+ }
398+
399+ /**
400+ * Implemented to be a <code>MenuElement</code> -- does nothing.
401+ *
402+ * @see #getSubElements
403+ */
404+ public void menuSelectionChanged(boolean isIncluded) {
405+ }
406+
407+ /**
408+ * Implemented to be a <code>MenuElement</code> -- returns the
409+ * menus in this menu bar.
410+ * This is the reason for implementing the <code>MenuElement</code>
411+ * interface -- so that the menu bar can be treated the same as
412+ * other menu elements.
413+ * @return an array of menu items in the menu bar.
414+ */
415+ public MenuElement[] getSubElements() {
416+ MenuElement result[];
417+ Vector<MenuElement> tmp = new Vector<MenuElement>();
418+ int c = getComponentCount();
419+ int i;
420+ Component m;
421+
422+ for(i=0 ; i < c ; i++) {
423+ m = getComponent(i);
424+ if(m instanceof MenuElement)
425+ tmp.addElement((MenuElement) m);
426+ }
427+
428+ result = new MenuElement[tmp.size()];
429+ for(i=0,c=tmp.size() ; i < c ; i++)
430+ result[i] = tmp.elementAt(i);
431+ return result;
432+ }
433+
434+ /**
435+ * Implemented to be a <code>MenuElement</code>. Returns this object.
436+ *
437+ * @return the current <code>Component</code> (this)
438+ * @see #getSubElements
439+ */
440+ public Component getComponent() {
441+ return this;
442+ }
443+
444+
445+ /**
446+ * Returns a string representation of this <code>JMenuBar</code>.
447+ * This method
448+ * is intended to be used only for debugging purposes, and the
449+ * content and format of the returned string may vary between
450+ * implementations. The returned string may be empty but may not
451+ * be <code>null</code>.
452+ *
453+ * @return a string representation of this <code>JMenuBar</code>
454+ */
455+ protected String paramString() {
456+ String paintBorderString = (paintBorder ?
457+ "true" : "false");
458+ String marginString = (margin != null ?
459+ margin.toString() : "");
460+
461+ return super.paramString() +
462+ ",margin=" + marginString +
463+ ",paintBorder=" + paintBorderString;
464+ }
465+
466+/////////////////
467+// Accessibility support
468+////////////////
469+
470+ /**
471+ * Gets the AccessibleContext associated with this JMenuBar.
472+ * For JMenuBars, the AccessibleContext takes the form of an
473+ * AccessibleJMenuBar.
474+ * A new AccessibleJMenuBar instance is created if necessary.
475+ *
476+ * @return an AccessibleJMenuBar that serves as the
477+ * AccessibleContext of this JMenuBar
478+ */
479+ public AccessibleContext getAccessibleContext() {
480+ if (accessibleContext == null) {
481+ accessibleContext = new AccessibleJMenuBar();
482+ }
483+ return accessibleContext;
484+ }
485+
486+ /**
487+ * This class implements accessibility support for the
488+ * <code>JMenuBar</code> class. It provides an implementation of the
489+ * Java Accessibility API appropriate to menu bar user-interface
490+ * elements.
491+ * <p>
492+ * <strong>Warning:</strong>
493+ * Serialized objects of this class will not be compatible with
494+ * future Swing releases. The current serialization support is
495+ * appropriate for short term storage or RMI between applications running
496+ * the same version of Swing. As of 1.4, support for long term storage
497+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
498+ * has been added to the <code>java.beans</code> package.
499+ * Please see {@link java.beans.XMLEncoder}.
500+ */
501+ protected class AccessibleJMenuBar extends AccessibleJComponent
502+ implements AccessibleSelection {
503+
504+ /**
505+ * Get the accessible state set of this object.
506+ *
507+ * @return an instance of AccessibleState containing the current state
508+ * of the object
509+ */
510+ public AccessibleStateSet getAccessibleStateSet() {
511+ AccessibleStateSet states = super.getAccessibleStateSet();
512+ return states;
513+ }
514+
515+ /**
516+ * Get the role of this object.
517+ *
518+ * @return an instance of AccessibleRole describing the role of the
519+ * object
520+ */
521+ public AccessibleRole getAccessibleRole() {
522+ return AccessibleRole.MENU_BAR;
523+ }
524+
525+ /**
526+ * Get the AccessibleSelection associated with this object. In the
527+ * implementation of the Java Accessibility API for this class,
528+ * return this object, which is responsible for implementing the
529+ * AccessibleSelection interface on behalf of itself.
530+ *
531+ * @return this object
532+ */
533+ public AccessibleSelection getAccessibleSelection() {
534+ return this;
535+ }
536+
537+ /**
538+ * Returns 1 if a menu is currently selected in this menu bar.
539+ *
540+ * @return 1 if a menu is currently selected, else 0
541+ */
542+ public int getAccessibleSelectionCount() {
543+ if (isSelected()) {
544+ return 1;
545+ } else {
546+ return 0;
547+ }
548+ }
549+
550+ /**
551+ * Returns the currently selected menu if one is selected,
552+ * otherwise null.
553+ */
554+ public Accessible getAccessibleSelection(int i) {
555+ if (isSelected()) {
556+ if (i != 0) { // single selection model for JMenuBar
557+ return null;
558+ }
559+ int j = getSelectionModel().getSelectedIndex();
560+ if (getComponentAtIndex(j) instanceof Accessible) {
561+ return (Accessible) getComponentAtIndex(j);
562+ }
563+ }
564+ return null;
565+ }
566+
567+ /**
568+ * Returns true if the current child of this object is selected.
569+ *
570+ * @param i the zero-based index of the child in this Accessible
571+ * object.
572+ * @see AccessibleContext#getAccessibleChild
573+ */
574+ public boolean isAccessibleChildSelected(int i) {
575+ return (i == getSelectionModel().getSelectedIndex());
576+ }
577+
578+ /**
579+ * Selects the nth menu in the menu bar, forcing it to
580+ * pop up. If another menu is popped up, this will force
581+ * it to close. If the nth menu is already selected, this
582+ * method has no effect.
583+ *
584+ * @param i the zero-based index of selectable items
585+ * @see #getAccessibleStateSet
586+ */
587+ public void addAccessibleSelection(int i) {
588+ // first close up any open menu
589+ int j = getSelectionModel().getSelectedIndex();
590+ if (i == j) {
591+ return;
592+ }
593+ if (j >= 0 && j < getMenuCount()) {
594+ JMenu menu = getMenu(j);
595+ if (menu != null) {
596+ MenuSelectionManager.defaultManager().setSelectedPath(null);
597+// menu.setPopupMenuVisible(false);
598+ }
599+ }
600+ // now popup the new menu
601+ getSelectionModel().setSelectedIndex(i);
602+ JMenu menu = getMenu(i);
603+ if (menu != null) {
604+ MenuElement me[] = new MenuElement[3];
605+ me[0] = JMenuBar.this;
606+ me[1] = menu;
607+ me[2] = menu.getPopupMenu();
608+ MenuSelectionManager.defaultManager().setSelectedPath(me);
609+// menu.setPopupMenuVisible(true);
610+ }
611+ }
612+
613+ /**
614+ * Removes the nth selected item in the object from the object's
615+ * selection. If the nth item isn't currently selected, this
616+ * method has no effect. Otherwise, it closes the popup menu.
617+ *
618+ * @param i the zero-based index of selectable items
619+ */
620+ public void removeAccessibleSelection(int i) {
621+ if (i >= 0 && i < getMenuCount()) {
622+ JMenu menu = getMenu(i);
623+ if (menu != null) {
624+ MenuSelectionManager.defaultManager().setSelectedPath(null);
625+// menu.setPopupMenuVisible(false);
626+ }
627+ getSelectionModel().setSelectedIndex(-1);
628+ }
629+ }
630+
631+ /**
632+ * Clears the selection in the object, so that nothing in the
633+ * object is selected. This will close any open menu.
634+ */
635+ public void clearAccessibleSelection() {
636+ int i = getSelectionModel().getSelectedIndex();
637+ if (i >= 0 && i < getMenuCount()) {
638+ JMenu menu = getMenu(i);
639+ if (menu != null) {
640+ MenuSelectionManager.defaultManager().setSelectedPath(null);
641+// menu.setPopupMenuVisible(false);
642+ }
643+ }
644+ getSelectionModel().setSelectedIndex(-1);
645+ }
646+
647+ /**
648+ * Normally causes every selected item in the object to be selected
649+ * if the object supports multiple selections. This method
650+ * makes no sense in a menu bar, and so does nothing.
651+ */
652+ public void selectAllAccessibleSelection() {
653+ }
654+ } // internal class AccessibleJMenuBar
655+
656+
657+ /**
658+ * Subclassed to check all the child menus.
659+ * @since 1.3
660+ */
661+ protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
662+ int condition, boolean pressed) {
663+ // See if we have a local binding.
664+ boolean retValue = super.processKeyBinding(ks, e, condition, pressed);
665+ if (!retValue) {
666+ MenuElement[] subElements = getSubElements();
667+ for (MenuElement subElement : subElements) {
668+ if (processBindingForKeyStrokeRecursive(
669+ subElement, ks, e, condition, pressed)) {
670+ return true;
671+ }
672+ }
673+ }
674+ return retValue;
675+ }
676+
677+ static boolean processBindingForKeyStrokeRecursive(MenuElement elem,
678+ KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
679+ if (elem == null) {
680+ return false;
681+ }
682+
683+ Component c = elem.getComponent();
684+
685+ if ( !(c.isVisible() || (c instanceof JPopupMenu)) || !c.isEnabled() ) {
686+ return false;
687+ }
688+
689+ if (c != null && c instanceof JComponent &&
690+ ((JComponent)c).processKeyBinding(ks, e, condition, pressed)) {
691+
692+ return true;
693+ }
694+
695+ MenuElement[] subElements = elem.getSubElements();
696+ for (MenuElement subElement : subElements) {
697+ if (processBindingForKeyStrokeRecursive(subElement, ks, e, condition, pressed)) {
698+ return true;
699+ // We don't, pass along to children JMenu's
700+ }
701+ }
702+ return false;
703+ }
704+
705+ /**
706+ * Overrides <code>JComponent.addNotify</code> to register this
707+ * menu bar with the current keyboard manager.
708+ */
709+ public void addNotify() {
710+ super.addNotify();
711+ KeyboardManager.getCurrentManager().registerMenuBar(this);
712+ }
713+
714+ /**
715+ * Overrides <code>JComponent.removeNotify</code> to unregister this
716+ * menu bar with the current keyboard manager.
717+ */
718+ public void removeNotify() {
719+ super.removeNotify();
720+ KeyboardManager.getCurrentManager().unregisterMenuBar(this);
721+ }
722+
723+
724+ private void writeObject(ObjectOutputStream s) throws IOException {
725+ s.defaultWriteObject();
726+ if (getUIClassID().equals(uiClassID)) {
727+ byte count = JComponent.getWriteObjCounter(this);
728+ JComponent.setWriteObjCounter(this, --count);
729+ if (count == 0 && ui != null) {
730+ ui.installUI(this);
731+ }
732+ }
733+
734+ Object[] kvData = new Object[4];
735+ int n = 0;
736+
737+ if (selectionModel instanceof Serializable) {
738+ kvData[n++] = "selectionModel";
739+ kvData[n++] = selectionModel;
740+ }
741+
742+ s.writeObject(kvData);
743+ }
744+
745+
746+ /**
747+ * See JComponent.readObject() for information about serialization
748+ * in Swing.
749+ */
750+ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
751+ {
752+ s.defaultReadObject();
753+ Object[] kvData = (Object[])(s.readObject());
754+
755+ for(int i = 0; i < kvData.length; i += 2) {
756+ if (kvData[i] == null) {
757+ break;
758+ }
759+ else if (kvData[i].equals("selectionModel")) {
760+ selectionModel = (SingleSelectionModel)kvData[i + 1];
761+ }
762+ }
763+
764+ }
765+}