src/macosx/classes/com/apple/laf/AquaComboBoxUI.java

Print this page


   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