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
185
186 final Object text = editor.getText();
187
188 final ListModel model = listBox.getModel();
189 final int items = model.getSize();
190 for (int i = 0; i < items; i++) {
191 final Object element = model.getElementAt(i);
192 if (element == null) continue;
193
194 final String asString = element.toString();
195 if (asString == null || !asString.equals(text)) continue;
196
197 popup.getList().setSelectedIndex(i);
198 return;
199 }
200
201 popup.getList().clearSelection();
202 }
203 }
204
205 class AquaCustomComboTextField extends JTextField {
206 public AquaCustomComboTextField() {
207 final InputMap inputMap = getInputMap();
208 inputMap.put(KeyStroke.getKeyStroke("DOWN"), highlightNextAction);
209 inputMap.put(KeyStroke.getKeyStroke("KP_DOWN"), highlightNextAction);
210 inputMap.put(KeyStroke.getKeyStroke("UP"), highlightPreviousAction);
211 inputMap.put(KeyStroke.getKeyStroke("KP_UP"), highlightPreviousAction);
212
213 inputMap.put(KeyStroke.getKeyStroke("HOME"), highlightFirstAction);
214 inputMap.put(KeyStroke.getKeyStroke("END"), highlightLastAction);
215 inputMap.put(KeyStroke.getKeyStroke("PAGE_UP"), highlightPageUpAction);
216 inputMap.put(KeyStroke.getKeyStroke("PAGE_DOWN"), highlightPageDownAction);
217
218 final Action action = getActionMap().get(JTextField.notifyAction);
219 inputMap.put(KeyStroke.getKeyStroke("ENTER"), new AbstractAction() {
220 public void actionPerformed(final ActionEvent e) {
221 if (popup.isVisible()) {
222 triggerSelectionEvent(comboBox, e);
223
224 if (editor instanceof AquaCustomComboTextField) {
225 ((AquaCustomComboTextField)editor).selectAll();
269 protected void installKeyboardActions() {
270 super.installKeyboardActions();
271
272 ActionMap actionMap = new ActionMapUIResource();
273
274 actionMap.put("aquaSelectNext", highlightNextAction);
275 actionMap.put("aquaSelectPrevious", highlightPreviousAction);
276 actionMap.put("aquaEnterPressed", triggerSelectionAction);
277 actionMap.put("aquaSpacePressed", toggleSelectionAction);
278
279 actionMap.put("aquaSelectHome", highlightFirstAction);
280 actionMap.put("aquaSelectEnd", highlightLastAction);
281 actionMap.put("aquaSelectPageUp", highlightPageUpAction);
282 actionMap.put("aquaSelectPageDown", highlightPageDownAction);
283
284 actionMap.put("aquaHidePopup", hideAction);
285
286 SwingUtilities.replaceUIActionMap(comboBox, actionMap);
287 }
288
289 private abstract class ComboBoxAction extends AbstractAction {
290 public void actionPerformed(final ActionEvent e) {
291 if (!comboBox.isEnabled() || !comboBox.isShowing()) {
292 return;
293 }
294
295 if (comboBox.isPopupVisible()) {
296 final AquaComboBoxUI ui = (AquaComboBoxUI)comboBox.getUI();
297 performComboBoxAction(ui);
298 } else {
299 comboBox.setPopupVisible(true);
300 }
301 }
302
303 abstract void performComboBoxAction(final AquaComboBoxUI ui);
304 }
305
306 /**
307 * Hilight _but do not select_ the next item in the list.
308 */
309 private Action highlightNextAction = new ComboBoxAction() {
310 @Override
311 public void performComboBoxAction(AquaComboBoxUI ui) {
312 final int si = listBox.getSelectedIndex();
313
314 if (si < comboBox.getModel().getSize() - 1) {
315 listBox.setSelectedIndex(si + 1);
316 listBox.ensureIndexIsVisible(si + 1);
317 }
318 comboBox.repaint();
319 }
320 };
321
322 /**
323 * Hilight _but do not select_ the previous item in the list.
324 */
325 private Action highlightPreviousAction = new ComboBoxAction() {
326 @Override
327 void performComboBoxAction(final AquaComboBoxUI ui) {
328 final int si = listBox.getSelectedIndex();
329 if (si > 0) {
330 listBox.setSelectedIndex(si - 1);
331 listBox.ensureIndexIsVisible(si - 1);
332 }
333 comboBox.repaint();
334 }
335 };
336
337 private Action highlightFirstAction = new ComboBoxAction() {
338 @Override
339 void performComboBoxAction(final AquaComboBoxUI ui) {
340 listBox.setSelectedIndex(0);
341 listBox.ensureIndexIsVisible(0);
342 }
343 };
344
345 private Action highlightLastAction = new ComboBoxAction() {
346 @Override
347 void performComboBoxAction(final AquaComboBoxUI ui) {
348 final int size = listBox.getModel().getSize();
349 listBox.setSelectedIndex(size - 1);
350 listBox.ensureIndexIsVisible(size - 1);
351 }
352 };
353
354 private Action highlightPageUpAction = new ComboBoxAction() {
355 @Override
356 void performComboBoxAction(final AquaComboBoxUI ui) {
357 final int current = listBox.getSelectedIndex();
358 final int first = listBox.getFirstVisibleIndex();
359
360 if (current != first) {
361 listBox.setSelectedIndex(first);
362 return;
363 }
364
365 final int page = listBox.getVisibleRect().height / listBox.getCellBounds(0, 0).height;
366 int target = first - page;
367 if (target < 0) target = 0;
368
369 listBox.ensureIndexIsVisible(target);
370 listBox.setSelectedIndex(target);
371 }
372 };
373
374 private Action highlightPageDownAction = new ComboBoxAction() {
375 @Override
376 void performComboBoxAction(final AquaComboBoxUI ui) {
377 final int current = listBox.getSelectedIndex();
378 final int last = listBox.getLastVisibleIndex();
379
380 if (current != last) {
381 listBox.setSelectedIndex(last);
382 return;
383 }
384
385 final int page = listBox.getVisibleRect().height / listBox.getCellBounds(0, 0).height;
386 final int end = listBox.getModel().getSize() - 1;
387 int target = last + page;
388 if (target > end) target = end;
389
390 listBox.ensureIndexIsVisible(target);
391 listBox.setSelectedIndex(target);
392 }
393 };
469 // Call the default button binding.
470 // This is a pretty messy way of passing an event through to the root pane
471 final JRootPane root = SwingUtilities.getRootPane(comboBox);
472 if (root == null) return;
473
474 final InputMap im = root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
475 final ActionMap am = root.getActionMap();
476 if (im == null || am == null) return;
477
478 final Object obj = im.get(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
479 if (obj == null) return;
480
481 final Action action = am.get(obj);
482 if (action == null) return;
483
484 action.actionPerformed(new ActionEvent(root, e.getID(), e.getActionCommand(), e.getWhen(), e.getModifiers()));
485 }
486
487 // This is somewhat messy. The difference here from BasicComboBoxUI.EnterAction is that
488 // arrow up or down does not automatically select the
489 private static final Action triggerSelectionAction = new AbstractAction() {
490 public void actionPerformed(final ActionEvent e) {
491 triggerSelectionEvent((JComboBox)e.getSource(), e);
492 }
493 };
494
495 private static final Action toggleSelectionAction = new AbstractAction() {
496 public void actionPerformed(final ActionEvent e) {
497 final JComboBox comboBox = (JComboBox)e.getSource();
498 if (!comboBox.isEnabled()) return;
499 if (comboBox.isEditable()) return;
500
501 final AquaComboBoxUI aquaUi = (AquaComboBoxUI)comboBox.getUI();
502
503 if (comboBox.isPopupVisible()) {
504 comboBox.setSelectedIndex(aquaUi.getPopup().getList().getSelectedIndex());
505 comboBox.setPopupVisible(false);
506 return;
507 }
508
509 comboBox.setPopupVisible(true);
510 }
511 };
512
513 private static Action hideAction = new AbstractAction() {
514 @Override
515 public void actionPerformed(final ActionEvent e) {
516 final JComboBox comboBox = (JComboBox)e.getSource();
517
518 if (comboBox.isPopupVisible()) {
519 comboBox.firePopupMenuCanceled();
520 comboBox.setPopupVisible(false);
521 }
522 }
523 };
524
525 public void applySizeFor(final JComponent c, final Size size) {
526 if (arrowButton == null) return;
527 final Border border = arrowButton.getBorder();
528 if (!(border instanceof AquaButtonBorder)) return;
529 final AquaButtonBorder aquaBorder = (AquaButtonBorder)border;
530 arrowButton.setBorder(aquaBorder.deriveBorderForSize(size));
531 }
532
|
1 /*
2 * Copyright (c) 2011, 2014, 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
185
186 final Object text = editor.getText();
187
188 final ListModel model = listBox.getModel();
189 final int items = model.getSize();
190 for (int i = 0; i < items; i++) {
191 final Object element = model.getElementAt(i);
192 if (element == null) continue;
193
194 final String asString = element.toString();
195 if (asString == null || !asString.equals(text)) continue;
196
197 popup.getList().setSelectedIndex(i);
198 return;
199 }
200
201 popup.getList().clearSelection();
202 }
203 }
204
205 @SuppressWarnings("serial") // Superclass is not serializable across versions
206 class AquaCustomComboTextField extends JTextField {
207 @SuppressWarnings("serial") // anonymous class
208 public AquaCustomComboTextField() {
209 final InputMap inputMap = getInputMap();
210 inputMap.put(KeyStroke.getKeyStroke("DOWN"), highlightNextAction);
211 inputMap.put(KeyStroke.getKeyStroke("KP_DOWN"), highlightNextAction);
212 inputMap.put(KeyStroke.getKeyStroke("UP"), highlightPreviousAction);
213 inputMap.put(KeyStroke.getKeyStroke("KP_UP"), highlightPreviousAction);
214
215 inputMap.put(KeyStroke.getKeyStroke("HOME"), highlightFirstAction);
216 inputMap.put(KeyStroke.getKeyStroke("END"), highlightLastAction);
217 inputMap.put(KeyStroke.getKeyStroke("PAGE_UP"), highlightPageUpAction);
218 inputMap.put(KeyStroke.getKeyStroke("PAGE_DOWN"), highlightPageDownAction);
219
220 final Action action = getActionMap().get(JTextField.notifyAction);
221 inputMap.put(KeyStroke.getKeyStroke("ENTER"), new AbstractAction() {
222 public void actionPerformed(final ActionEvent e) {
223 if (popup.isVisible()) {
224 triggerSelectionEvent(comboBox, e);
225
226 if (editor instanceof AquaCustomComboTextField) {
227 ((AquaCustomComboTextField)editor).selectAll();
271 protected void installKeyboardActions() {
272 super.installKeyboardActions();
273
274 ActionMap actionMap = new ActionMapUIResource();
275
276 actionMap.put("aquaSelectNext", highlightNextAction);
277 actionMap.put("aquaSelectPrevious", highlightPreviousAction);
278 actionMap.put("aquaEnterPressed", triggerSelectionAction);
279 actionMap.put("aquaSpacePressed", toggleSelectionAction);
280
281 actionMap.put("aquaSelectHome", highlightFirstAction);
282 actionMap.put("aquaSelectEnd", highlightLastAction);
283 actionMap.put("aquaSelectPageUp", highlightPageUpAction);
284 actionMap.put("aquaSelectPageDown", highlightPageDownAction);
285
286 actionMap.put("aquaHidePopup", hideAction);
287
288 SwingUtilities.replaceUIActionMap(comboBox, actionMap);
289 }
290
291 @SuppressWarnings("serial") // Superclass is not serializable across versions
292 private abstract class ComboBoxAction extends AbstractAction {
293 public void actionPerformed(final ActionEvent e) {
294 if (!comboBox.isEnabled() || !comboBox.isShowing()) {
295 return;
296 }
297
298 if (comboBox.isPopupVisible()) {
299 final AquaComboBoxUI ui = (AquaComboBoxUI)comboBox.getUI();
300 performComboBoxAction(ui);
301 } else {
302 comboBox.setPopupVisible(true);
303 }
304 }
305
306 abstract void performComboBoxAction(final AquaComboBoxUI ui);
307 }
308
309 /**
310 * Hilight _but do not select_ the next item in the list.
311 */
312 @SuppressWarnings("serial") // anonymous class
313 private Action highlightNextAction = new ComboBoxAction() {
314 @Override
315 public void performComboBoxAction(AquaComboBoxUI ui) {
316 final int si = listBox.getSelectedIndex();
317
318 if (si < comboBox.getModel().getSize() - 1) {
319 listBox.setSelectedIndex(si + 1);
320 listBox.ensureIndexIsVisible(si + 1);
321 }
322 comboBox.repaint();
323 }
324 };
325
326 /**
327 * Hilight _but do not select_ the previous item in the list.
328 */
329 @SuppressWarnings("serial") // anonymous class
330 private Action highlightPreviousAction = new ComboBoxAction() {
331 @Override
332 void performComboBoxAction(final AquaComboBoxUI ui) {
333 final int si = listBox.getSelectedIndex();
334 if (si > 0) {
335 listBox.setSelectedIndex(si - 1);
336 listBox.ensureIndexIsVisible(si - 1);
337 }
338 comboBox.repaint();
339 }
340 };
341
342 @SuppressWarnings("serial") // anonymous class
343 private Action highlightFirstAction = new ComboBoxAction() {
344 @Override
345 void performComboBoxAction(final AquaComboBoxUI ui) {
346 listBox.setSelectedIndex(0);
347 listBox.ensureIndexIsVisible(0);
348 }
349 };
350
351 @SuppressWarnings("serial") // anonymous class
352 private Action highlightLastAction = new ComboBoxAction() {
353 @Override
354 void performComboBoxAction(final AquaComboBoxUI ui) {
355 final int size = listBox.getModel().getSize();
356 listBox.setSelectedIndex(size - 1);
357 listBox.ensureIndexIsVisible(size - 1);
358 }
359 };
360
361 @SuppressWarnings("serial") // anonymous class
362 private Action highlightPageUpAction = new ComboBoxAction() {
363 @Override
364 void performComboBoxAction(final AquaComboBoxUI ui) {
365 final int current = listBox.getSelectedIndex();
366 final int first = listBox.getFirstVisibleIndex();
367
368 if (current != first) {
369 listBox.setSelectedIndex(first);
370 return;
371 }
372
373 final int page = listBox.getVisibleRect().height / listBox.getCellBounds(0, 0).height;
374 int target = first - page;
375 if (target < 0) target = 0;
376
377 listBox.ensureIndexIsVisible(target);
378 listBox.setSelectedIndex(target);
379 }
380 };
381
382 @SuppressWarnings("serial") // anonymous class
383 private Action highlightPageDownAction = new ComboBoxAction() {
384 @Override
385 void performComboBoxAction(final AquaComboBoxUI ui) {
386 final int current = listBox.getSelectedIndex();
387 final int last = listBox.getLastVisibleIndex();
388
389 if (current != last) {
390 listBox.setSelectedIndex(last);
391 return;
392 }
393
394 final int page = listBox.getVisibleRect().height / listBox.getCellBounds(0, 0).height;
395 final int end = listBox.getModel().getSize() - 1;
396 int target = last + page;
397 if (target > end) target = end;
398
399 listBox.ensureIndexIsVisible(target);
400 listBox.setSelectedIndex(target);
401 }
402 };
478 // Call the default button binding.
479 // This is a pretty messy way of passing an event through to the root pane
480 final JRootPane root = SwingUtilities.getRootPane(comboBox);
481 if (root == null) return;
482
483 final InputMap im = root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
484 final ActionMap am = root.getActionMap();
485 if (im == null || am == null) return;
486
487 final Object obj = im.get(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
488 if (obj == null) return;
489
490 final Action action = am.get(obj);
491 if (action == null) return;
492
493 action.actionPerformed(new ActionEvent(root, e.getID(), e.getActionCommand(), e.getWhen(), e.getModifiers()));
494 }
495
496 // This is somewhat messy. The difference here from BasicComboBoxUI.EnterAction is that
497 // arrow up or down does not automatically select the
498 @SuppressWarnings("serial") // anonymous class
499 private static final Action triggerSelectionAction = new AbstractAction() {
500 public void actionPerformed(final ActionEvent e) {
501 triggerSelectionEvent((JComboBox)e.getSource(), e);
502 }
503 };
504
505 @SuppressWarnings("serial") // anonymous class
506 private static final Action toggleSelectionAction = new AbstractAction() {
507 public void actionPerformed(final ActionEvent e) {
508 final JComboBox comboBox = (JComboBox)e.getSource();
509 if (!comboBox.isEnabled()) return;
510 if (comboBox.isEditable()) return;
511
512 final AquaComboBoxUI aquaUi = (AquaComboBoxUI)comboBox.getUI();
513
514 if (comboBox.isPopupVisible()) {
515 comboBox.setSelectedIndex(aquaUi.getPopup().getList().getSelectedIndex());
516 comboBox.setPopupVisible(false);
517 return;
518 }
519
520 comboBox.setPopupVisible(true);
521 }
522 };
523
524 @SuppressWarnings("serial") // anonymous class
525 private static Action hideAction = new AbstractAction() {
526 @Override
527 public void actionPerformed(final ActionEvent e) {
528 final JComboBox comboBox = (JComboBox)e.getSource();
529
530 if (comboBox.isPopupVisible()) {
531 comboBox.firePopupMenuCanceled();
532 comboBox.setPopupVisible(false);
533 }
534 }
535 };
536
537 public void applySizeFor(final JComponent c, final Size size) {
538 if (arrowButton == null) return;
539 final Border border = arrowButton.getBorder();
540 if (!(border instanceof AquaButtonBorder)) return;
541 final AquaButtonBorder aquaBorder = (AquaButtonBorder)border;
542 arrowButton.setBorder(aquaBorder.deriveBorderForSize(size));
543 }
544
|