1 /* |
|
2 * CDDL HEADER START |
|
3 * |
|
4 * The contents of this file are subject to the terms of the |
|
5 * Common Development and Distribution License (the "License"). |
|
6 * You may not use this file except in compliance with the License. |
|
7 * |
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 * or http://www.opensolaris.org/os/licensing. |
|
10 * See the License for the specific language governing permissions |
|
11 * and limitations under the License. |
|
12 * |
|
13 * When distributing Covered Code, include this CDDL HEADER in each |
|
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 * If applicable, add the following below this CDDL HEADER, with the |
|
16 * fields enclosed by brackets "[]" replaced with your own identifying |
|
17 * information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 * |
|
19 * CDDL HEADER END |
|
20 */ |
|
21 |
|
22 /* |
|
23 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. |
|
24 */ |
|
25 |
|
26 package com.oracle.solaris.vp.util.swing; |
|
27 |
|
28 import java.awt.*; |
|
29 import java.awt.event.*; |
|
30 import javax.swing.*; |
|
31 import javax.swing.plaf.basic.BasicComboPopup; |
|
32 import com.oracle.solaris.vp.util.swing.event.ItemListeners; |
|
33 |
|
34 @SuppressWarnings({"serial"}) |
|
35 public class PopupList implements ItemSelectable { |
|
36 // |
|
37 // Static data |
|
38 // |
|
39 |
|
40 // Taken from the JList API |
|
41 private static final int MAX_VISIBLE_ROW_COUNT = 8; |
|
42 |
|
43 // |
|
44 // Instance data |
|
45 // |
|
46 |
|
47 private JComponent component; |
|
48 private BasicComboPopup popup; |
|
49 private JComboBox combo; |
|
50 private ItemListeners listeners = new ItemListeners(); |
|
51 |
|
52 // |
|
53 // Constructors |
|
54 // |
|
55 |
|
56 public PopupList(JComponent component) { |
|
57 this.component = component; |
|
58 |
|
59 configureComboBox(); |
|
60 configurePopup(); |
|
61 configureList(); |
|
62 } |
|
63 |
|
64 public PopupList(JButton button) { |
|
65 this((JComponent)button); |
|
66 |
|
67 button.addActionListener( |
|
68 new AbstractAction() { |
|
69 @Override |
|
70 public void actionPerformed(ActionEvent e) { |
|
71 show(); |
|
72 } |
|
73 }); |
|
74 } |
|
75 |
|
76 public PopupList(JComponent component, ComboBoxModel model) { |
|
77 this(component); |
|
78 setModel(model); |
|
79 } |
|
80 |
|
81 public PopupList(JButton button, ComboBoxModel model) { |
|
82 this(button); |
|
83 setModel(model); |
|
84 } |
|
85 |
|
86 // |
|
87 // ItemSelectable methods |
|
88 // |
|
89 |
|
90 @Override |
|
91 public void addItemListener(ItemListener l) { |
|
92 listeners.add(l); |
|
93 } |
|
94 |
|
95 @Override |
|
96 public Object[] getSelectedObjects() { |
|
97 return popup.getList().getSelectedValues(); |
|
98 } |
|
99 |
|
100 @Override |
|
101 public void removeItemListener(ItemListener l) { |
|
102 listeners.remove(l); |
|
103 } |
|
104 |
|
105 // |
|
106 // PopupList methods |
|
107 // |
|
108 |
|
109 public ComboBoxModel getModel() { |
|
110 return combo.getModel(); |
|
111 } |
|
112 |
|
113 public JComponent getComponent() { |
|
114 return component; |
|
115 } |
|
116 |
|
117 public BasicComboPopup getPopup() { |
|
118 return popup; |
|
119 } |
|
120 |
|
121 public void hide() { |
|
122 popup.setVisible(false); |
|
123 |
|
124 // Window change -- prefer requestFocus to requestFocusInWindow |
|
125 component.requestFocus(); |
|
126 } |
|
127 |
|
128 protected void itemSelected() { |
|
129 hide(); |
|
130 |
|
131 Object item = popup.getList().getSelectedValue(); |
|
132 ItemEvent e = new ItemEvent( |
|
133 this, ItemEvent.ITEM_STATE_CHANGED, item, ItemEvent.SELECTED); |
|
134 |
|
135 listeners.itemStateChanged(e); |
|
136 } |
|
137 |
|
138 public void setModel(ComboBoxModel model) { |
|
139 combo.setModel(model); |
|
140 } |
|
141 |
|
142 public void show() { |
|
143 JList list = popup.getList(); |
|
144 int size = list.getModel().getSize(); |
|
145 list.setVisibleRowCount(size < MAX_VISIBLE_ROW_COUNT ? |
|
146 size : MAX_VISIBLE_ROW_COUNT); |
|
147 |
|
148 combo.setSelectedIndex(-1); |
|
149 popup.show(component, 0, component.getHeight()); |
|
150 |
|
151 Window window = SwingUtilities.windowForComponent(popup); |
|
152 if (window != null) { |
|
153 window.setFocusableWindowState(true); |
|
154 } |
|
155 |
|
156 // Window change -- prefer requestFocus to requestFocusInWindow |
|
157 list.requestFocus(); |
|
158 } |
|
159 |
|
160 public void showOnDownArrowKey() { |
|
161 Action showAction = |
|
162 new AbstractAction() { |
|
163 @Override |
|
164 public void actionPerformed(ActionEvent e) { |
|
165 show(); |
|
166 } |
|
167 }; |
|
168 |
|
169 GUIUtil.installKeyBinding(component, JComponent.WHEN_FOCUSED, |
|
170 "showPopup", showAction, KeyEvent.VK_DOWN, KeyEvent.VK_KP_DOWN); |
|
171 } |
|
172 |
|
173 public void showOnMousePress() { |
|
174 component.addMouseListener( |
|
175 new MouseAdapter() { |
|
176 @Override |
|
177 public void mousePressed(MouseEvent e) { |
|
178 if (e.getModifiersEx() == InputEvent.BUTTON1_DOWN_MASK) { |
|
179 show(); |
|
180 } |
|
181 } |
|
182 }); |
|
183 } |
|
184 |
|
185 // |
|
186 // Private methods |
|
187 // |
|
188 |
|
189 private void configureComboBox() { |
|
190 combo = new JComboBox(); |
|
191 combo.addItemListener( |
|
192 new ItemListener() { |
|
193 @Override |
|
194 public void itemStateChanged(ItemEvent e) { |
|
195 if (e.getStateChange() == ItemEvent.SELECTED) { |
|
196 itemSelected(); |
|
197 } |
|
198 } |
|
199 }); |
|
200 } |
|
201 |
|
202 private void configureList() { |
|
203 JList list = popup.getList(); |
|
204 list.setBackground(Color.white); |
|
205 list.setOpaque(true); |
|
206 list.setFocusable(true); |
|
207 } |
|
208 |
|
209 private void configurePopup() { |
|
210 popup = new BasicComboPopup(combo); |
|
211 popup.setFocusable(true); |
|
212 |
|
213 Action commitAction = |
|
214 new AbstractAction() { |
|
215 @Override |
|
216 public void actionPerformed(ActionEvent e) { |
|
217 itemSelected(); |
|
218 } |
|
219 }; |
|
220 |
|
221 GUIUtil.installKeyBinding(popup, |
|
222 JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, "commitPopup", |
|
223 commitAction, KeyEvent.VK_ENTER); |
|
224 |
|
225 Action cancelAction = |
|
226 new AbstractAction() { |
|
227 @Override |
|
228 public void actionPerformed(ActionEvent e) { |
|
229 hide(); |
|
230 } |
|
231 }; |
|
232 |
|
233 GUIUtil.installKeyBinding(popup, |
|
234 JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, "cancelPopup", |
|
235 cancelAction, KeyEvent.VK_ESCAPE); |
|
236 } |
|
237 |
|
238 // |
|
239 // Static methods |
|
240 // |
|
241 |
|
242 public static void main(String s[]) { |
|
243 String[] data = { |
|
244 "Bee", "Skunk" |
|
245 }; |
|
246 ComboBoxModel model = new DefaultComboBoxModel(data); |
|
247 |
|
248 JButton b = new JButton("Hello"); |
|
249 |
|
250 PopupList popup = new PopupList(b, model); |
|
251 popup.showOnDownArrowKey(); |
|
252 |
|
253 popup.addItemListener( |
|
254 new ItemListener() { |
|
255 @Override |
|
256 public void itemStateChanged(ItemEvent e) { |
|
257 System.out.printf("%s\n", e.getItem()); |
|
258 } |
|
259 }); |
|
260 |
|
261 JFrame frame = new JFrame(); |
|
262 Container c = frame.getContentPane(); |
|
263 c.setLayout(new BorderLayout()); |
|
264 c.add(b, BorderLayout.CENTER); |
|
265 frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); |
|
266 frame.pack(); |
|
267 frame.setVisible(true); |
|
268 } |
|
269 } |
|