    rev 48858 : Work in progress for JDK-6303622
    Use generic in Swing components like JComboBox
    1. Added generic return type and parameter type for JComboBox.
    2. Modified JList related classes as well.
    3. Reverted the changes made to "getSelectedValues" as suggested by Joe.
    4. Modified files that were failing on Linux and Mac as well.

       1 /*
       2  * Copyright (c) 2011, 2013, 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
      27 package sun.lwawt;
      28
      29 import java.awt.*;
      30 import java.awt.event.ItemEvent;
      31 import java.awt.event.ItemListener;
      32 import java.awt.peer.ChoicePeer;
      33
      34 import javax.accessibility.Accessible;
      35 import javax.swing.*;
      36
      37 /**
      38  * Lightweight implementation of {@link ChoicePeer}. Delegates most of the work
      39  * to the {@link JComboBox}.
      40  */
      41 final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>>
      42         implements ChoicePeer, ItemListener {
      43
      44     /**
      45      * According to Choice specification item events are sent in response to
      46      * user input, but not in response to calls to select(). But JComboBox are
      47      * sent item events in both cases. Should be used under delegateLock.
      48      */
      49     private boolean skipPostMessage;
      50
      51     LWChoicePeer(final Choice target,
      52                  final PlatformComponent platformComponent) {
      53         super(target, platformComponent);
      54     }
      55
      56     @Override
      57     JComboBox<String> createDelegate() {
      58         return new JComboBoxDelegate();
      59     }
      60
      61     @Override
      62     void initializeImpl() {
      63         super.initializeImpl();
      64         final Choice choice = getTarget();
      65         final JComboBox<String> combo = getDelegate();
      66         synchronized (getDelegateLock()) {
      67             final int count = choice.getItemCount();
      68             for (int i = 0; i < count; ++i) {
      69                 combo.addItem(choice.getItem(i));
      70             }
      71             select(choice.getSelectedIndex());
      72
      73             // NOTE: the listener must be added at the very end, otherwise it
      74             // fires events upon initialization of the combo box.
      75             combo.addItemListener(this);
      76         }
      77     }
      78
      79     @Override
      80     public void itemStateChanged(final ItemEvent e) {
      81         // AWT Choice sends SELECTED event only whereas JComboBox
      82         // sends both SELECTED and DESELECTED.
      83         if (e.getStateChange() == ItemEvent.SELECTED) {
      84             synchronized (getDelegateLock()) {
      85                 if (skipPostMessage) {
      86                     return;
      87                 }
      88                 getTarget().select(getDelegate().getSelectedIndex());
      89             }
      90             postEvent(new ItemEvent(getTarget(), ItemEvent.ITEM_STATE_CHANGED,
      91                                     e.getItem(), ItemEvent.SELECTED));
      92         }
      93     }
      94
      95     @Override
      96     public void add(final String item, final int index) {
      97         synchronized (getDelegateLock()) {
      98             getDelegate().insertItemAt(item, index);
      99         }
     100     }
     101
     102     @Override
     103     public void remove(final int index) {
     104         synchronized (getDelegateLock()) {
     105             // We shouldn't post event, if selected item was removed.
     106             skipPostMessage = true;
     107             getDelegate().removeItemAt(index);
     108             skipPostMessage = false;
     109         }
     110     }
     111
     112     @Override
     113     public void removeAll() {
     114         synchronized (getDelegateLock()) {
     115             getDelegate().removeAllItems();
     116         }
     117     }
     118
     119     @Override
     120     public void select(final int index) {
     121         synchronized (getDelegateLock()) {
     122             if (index != getDelegate().getSelectedIndex()) {
     123                 skipPostMessage = true;
     124                 getDelegate().setSelectedIndex(index);
     125                 skipPostMessage = false;
     126             }
     127         }
     128     }
     129
     130     @Override
     131     public boolean isFocusable() {
     132         return true;
     133     }
     134
     135     @SuppressWarnings("serial")// Safe: outer class is non-serializable.
     136     private final class JComboBoxDelegate extends JComboBox<String> {
     137
     138         // Empty non private constructor was added because access to this
     139         // class shouldn't be emulated by a synthetic accessor method.
     140         JComboBoxDelegate() {
     141             super();
     142         }
     143
     144         @Override
     145         public boolean hasFocus() {
     146             return getTarget().hasFocus();
     147         }
     148
     149         //Needed for proper popup menu location
     150         @Override
     151         public Point getLocationOnScreen() {
     152             return LWChoicePeer.this.getLocationOnScreen();
     153         }
     154
     155         /**
     156          * We should post ITEM_STATE_CHANGED event when the same element is
     157          * reselected.
     158          */
     159         @Override
     160         public void setSelectedItem(final Object anObject) {
     161             final Object oldSelection = selectedItemReminder;
     162             if (oldSelection != null && oldSelection.equals(anObject)) {
     163                 selectedItemChanged();
     164             }
     165             super.setSelectedItem(anObject);
     166         }
     167
     168         @Override
     169         public void firePopupMenuWillBecomeVisible() {
     170             super.firePopupMenuWillBecomeVisible();
     171             SwingUtilities.invokeLater(() -> {
     172                 JPopupMenu popupMenu = getPopupMenu();
     173                 // Need to override the invoker for proper grab handling
     174                 if (popupMenu != null
     175                         && popupMenu.isShowing()
     176                         && popupMenu.getInvoker() != getTarget()) {
     177                     // The popup is now visible with correct location
     178                     // Save it and restore after toggling visibility and changing invoker
     179                     Point loc = popupMenu.getLocationOnScreen();
     180                     SwingUtilities.convertPointFromScreen(loc, this);
     181                     popupMenu.setVisible(false);
     182                     popupMenu.show(getTarget(), loc.x, loc.y);
     183                 }
     184             });
     185         }
     186
     187         private JPopupMenu getPopupMenu() {
     188             for (int i = 0; i < getAccessibleContext().getAccessibleChildrenCount(); i++) {
     189                 Accessible child = getAccessibleContext().getAccessibleChild(i);
     190                 if (child instanceof JPopupMenu) {
     191                     return  (JPopupMenu) child;
     192                 }
     193             }
     194             return null;
     195         }
     196     }
     197 }
    --- EOF ---