1 /*
2  * Copyright (c) 1996, 2018, 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 package sun.awt.windows;
26 
27 import java.awt.*;
28 import java.awt.peer.*;
29 import java.awt.event.ItemEvent;
30 import java.awt.event.WindowEvent;
31 import java.awt.event.WindowListener;
32 import java.awt.event.WindowAdapter;
33 
34 import sun.awt.AWTAccessor;
35 import sun.awt.SunToolkit;
36 
37 final class WChoicePeer extends WComponentPeer implements ChoicePeer {
38 
39     // WComponentPeer overrides
40 
41     @Override
getMinimumSize()42     public Dimension getMinimumSize() {
43         FontMetrics fm = getFontMetrics(((Choice)target).getFont());
44         Choice c = (Choice)target;
45         int w = 0;
46         for (int i = c.getItemCount() ; i-- > 0 ;) {
47             w = Math.max(fm.stringWidth(c.getItem(i)), w);
48         }
49         return new Dimension(28 + w, Math.max(fm.getHeight() + 6, 15));
50     }
51     @Override
isFocusable()52     public boolean isFocusable() {
53         return true;
54     }
55 
56     // ChoicePeer implementation
57 
58     @Override
select(int index)59     public native void select(int index);
60 
61     @Override
add(String item, int index)62     public void add(String item, int index) {
63         addItems(new String[] {item}, index);
64     }
65 
66     @Override
shouldClearRectBeforePaint()67     public boolean shouldClearRectBeforePaint() {
68         return false;
69     }
70 
71     @Override
removeAll()72     public native void removeAll();
73     @Override
remove(int index)74     public native void remove(int index);
75 
addItems(String[] items, int index)76     public native void addItems(String[] items, int index);
77 
78     @Override
reshape(int x, int y, int width, int height)79     public synchronized native void reshape(int x, int y, int width, int height);
80 
81     private WindowListener windowListener;
82 
83     // Toolkit & peer internals
84 
WChoicePeer(Choice target)85     WChoicePeer(Choice target) {
86         super(target);
87     }
88 
89     @Override
create(WComponentPeer parent)90     native void create(WComponentPeer parent);
91 
92     @Override
initialize()93     void initialize() {
94         Choice opt = (Choice)target;
95         int itemCount = opt.getItemCount();
96         if (itemCount > 0) {
97             String[] items = new String[itemCount];
98             for (int i=0; i < itemCount; i++) {
99                 items[i] = opt.getItem(i);
100             }
101             addItems(items, 0);
102             if (opt.getSelectedIndex() >= 0) {
103                 select(opt.getSelectedIndex());
104             }
105         }
106 
107         Window parentWindow = SunToolkit.getContainingWindow((Component)target);
108         if (parentWindow != null) {
109             final WWindowPeer wpeer = AWTAccessor.getComponentAccessor()
110                                                  .getPeer(parentWindow);
111             if (wpeer != null) {
112                 windowListener = new WindowAdapter() {
113                         @Override
114                         public void windowIconified(WindowEvent e) {
115                             closeList();
116                         }
117                         @Override
118                         public void windowClosing(WindowEvent e) {
119                             closeList();
120                         }
121                     };
122                 wpeer.addWindowListener(windowListener);
123             }
124         }
125         super.initialize();
126     }
127 
128     @Override
disposeImpl()129     protected void disposeImpl() {
130         // TODO: we should somehow reset the listener when the choice
131         // is moved to another toplevel without destroying its peer.
132         Window parentWindow = SunToolkit.getContainingWindow((Component)target);
133         if (parentWindow != null) {
134             final WWindowPeer wpeer = AWTAccessor.getComponentAccessor()
135                                                 .getPeer(parentWindow);
136             if (wpeer != null) {
137                 wpeer.removeWindowListener(windowListener);
138             }
139         }
140         super.disposeImpl();
141     }
142 
143     // native callbacks
144 
handleAction(final int index)145     void handleAction(final int index) {
146         final Choice c = (Choice)target;
147         WToolkit.executeOnEventHandlerThread(c, new Runnable() {
148             @Override
149             public void run() {
150                 c.select(index);
151                 postEvent(new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED,
152                                 c.getItem(index), ItemEvent.SELECTED));
153             }
154         });
155     }
156 
getDropDownHeight()157     int getDropDownHeight() {
158         Choice c = (Choice)target;
159         FontMetrics fm = getFontMetrics(c.getFont());
160         int maxItems = Math.min(c.getItemCount(), 8);
161         return fm.getHeight() * maxItems;
162     }
163 
closeList()164     native void closeList();
165 }
166