4632N/A/*
6070N/A * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/Apackage com.apple.laf;
4632N/A
4632N/Aimport java.awt.*;
4632N/Aimport java.awt.event.*;
4632N/A
4632N/Aimport javax.accessibility.*;
4632N/Aimport javax.swing.*;
4632N/Aimport javax.swing.border.Border;
4632N/Aimport javax.swing.event.*;
4632N/Aimport javax.swing.plaf.*;
4632N/Aimport javax.swing.plaf.basic.*;
4632N/Aimport com.apple.laf.ClientPropertyApplicator.Property;
4632N/Aimport apple.laf.JRSUIConstants.Size;
4632N/A
4632N/Aimport com.apple.laf.AquaUtilControlSize.Sizeable;
4632N/Aimport com.apple.laf.AquaUtils.RecyclableSingleton;
4632N/A
4632N/A// Inspired by MetalComboBoxUI, which also has a combined text-and-arrow button for noneditables
4632N/Apublic class AquaComboBoxUI extends BasicComboBoxUI implements Sizeable {
4632N/A static final String POPDOWN_CLIENT_PROPERTY_KEY = "JComboBox.isPopDown";
4632N/A static final String ISSQUARE_CLIENT_PROPERTY_KEY = "JComboBox.isSquare";
4632N/A
4632N/A public static ComponentUI createUI(final JComponent c) {
4632N/A return new AquaComboBoxUI();
4632N/A }
4632N/A
4632N/A private boolean wasOpaque;
4632N/A public void installUI(final JComponent c) {
4632N/A super.installUI(c);
4632N/A
4632N/A // this doesn't work right now, because the JComboBox.init() method calls
4632N/A // .setOpaque(false) directly, and doesn't allow the LaF to decided. Bad Sun!
4632N/A LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
4632N/A
4632N/A wasOpaque = c.isOpaque();
4632N/A c.setOpaque(false);
4632N/A }
4632N/A
4632N/A public void uninstallUI(final JComponent c) {
4632N/A c.setOpaque(wasOpaque);
4632N/A super.uninstallUI(c);
4632N/A }
4632N/A
4632N/A protected void installListeners() {
4632N/A super.installListeners();
4632N/A AquaUtilControlSize.addSizePropertyListener(comboBox);
4632N/A }
4632N/A
4632N/A protected void uninstallListeners() {
4632N/A AquaUtilControlSize.removeSizePropertyListener(comboBox);
4632N/A super.uninstallListeners();
4632N/A }
4632N/A
4632N/A protected void installComponents() {
4632N/A super.installComponents();
4632N/A
4632N/A // client properties must be applied after the components have been installed,
4632N/A // because isSquare and isPopdown are applied to the installed button
4632N/A getApplicator().attachAndApplyClientProperties(comboBox);
4632N/A }
4632N/A
4632N/A protected void uninstallComponents() {
4632N/A getApplicator().removeFrom(comboBox);
4632N/A super.uninstallComponents();
4632N/A }
4632N/A
4632N/A protected ItemListener createItemListener() {
4632N/A return new ItemListener() {
4632N/A long lastBlink = 0L;
4632N/A public void itemStateChanged(final ItemEvent e) {
4632N/A if (e.getStateChange() != ItemEvent.SELECTED) return;
4632N/A if (!popup.isVisible()) return;
4632N/A
4632N/A // sometimes, multiple selection changes can occur while the popup is up,
4632N/A // and blinking more than "once" (in a second) is not desirable
4632N/A final long now = System.currentTimeMillis();
4632N/A if (now - 1000 < lastBlink) return;
4632N/A lastBlink = now;
4632N/A
4632N/A final JList itemList = popup.getList();
4632N/A final ListUI listUI = itemList.getUI();
4632N/A if (!(listUI instanceof AquaListUI)) return;
4632N/A final AquaListUI aquaListUI = (AquaListUI)listUI;
4632N/A
4632N/A final int selectedIndex = comboBox.getSelectedIndex();
4632N/A final ListModel dataModel = itemList.getModel();
4632N/A if (dataModel == null) return;
4632N/A
4632N/A final Object value = dataModel.getElementAt(selectedIndex);
4632N/A AquaUtils.blinkMenu(new AquaUtils.Selectable() {
4632N/A public void paintSelected(final boolean selected) {
4632N/A aquaListUI.repaintCell(value, selectedIndex, selected);
4632N/A }
4632N/A });
4632N/A }
4632N/A };
4632N/A }
4632N/A
4632N/A public void paint(final Graphics g, final JComponent c) {
4632N/A // this space intentionally left blank
4632N/A }
4632N/A
4632N/A protected ListCellRenderer createRenderer() {
4632N/A return new AquaComboBoxRenderer(comboBox);
4632N/A }
4632N/A
4632N/A protected ComboPopup createPopup() {
4632N/A return new AquaComboBoxPopup(comboBox);
4632N/A }
4632N/A
4632N/A protected JButton createArrowButton() {
4632N/A return new AquaComboBoxButton(this, comboBox, currentValuePane, listBox);
4632N/A }
4632N/A
4632N/A protected ComboBoxEditor createEditor() {
4632N/A return new AquaComboBoxEditor();
4632N/A }
4632N/A
6070N/A final class AquaComboBoxEditor extends BasicComboBoxEditor
6070N/A implements UIResource, DocumentListener {
6070N/A
6070N/A AquaComboBoxEditor() {
4632N/A super();
4632N/A editor = new AquaCustomComboTextField();
4632N/A editor.addFocusListener(this);
4632N/A editor.getDocument().addDocumentListener(this);
4632N/A }
4632N/A
6070N/A @Override
4632N/A public void focusGained(final FocusEvent e) {
6070N/A if (arrowButton != null) {
6070N/A arrowButton.repaint();
6070N/A }
4632N/A }
4632N/A
6070N/A @Override
4632N/A public void focusLost(final FocusEvent e) {
6070N/A if (arrowButton != null) {
6070N/A arrowButton.repaint();
6070N/A }
4632N/A }
4632N/A
6070N/A @Override
4632N/A public void changedUpdate(final DocumentEvent e) {
4632N/A editorTextChanged();
4632N/A }
4632N/A
6070N/A @Override
4632N/A public void insertUpdate(final DocumentEvent e) {
4632N/A editorTextChanged();
4632N/A }
4632N/A
6070N/A @Override
4632N/A public void removeUpdate(final DocumentEvent e) {
4632N/A editorTextChanged();
4632N/A }
4632N/A
6070N/A private void editorTextChanged() {
4632N/A if (!popup.isVisible()) return;
4632N/A
4632N/A final Object text = editor.getText();
4632N/A
4632N/A final ListModel model = listBox.getModel();
4632N/A final int items = model.getSize();
4632N/A for (int i = 0; i < items; i++) {
4632N/A final Object element = model.getElementAt(i);
4632N/A if (element == null) continue;
4632N/A
4632N/A final String asString = element.toString();
4632N/A if (asString == null || !asString.equals(text)) continue;
4632N/A
4632N/A popup.getList().setSelectedIndex(i);
4632N/A return;
4632N/A }
4632N/A
4632N/A popup.getList().clearSelection();
4632N/A }
4632N/A }
4632N/A
4632N/A class AquaCustomComboTextField extends JTextField {
4632N/A public AquaCustomComboTextField() {
4632N/A final InputMap inputMap = getInputMap();
4632N/A inputMap.put(KeyStroke.getKeyStroke("DOWN"), highlightNextAction);
4632N/A inputMap.put(KeyStroke.getKeyStroke("KP_DOWN"), highlightNextAction);
4632N/A inputMap.put(KeyStroke.getKeyStroke("UP"), highlightPreviousAction);
4632N/A inputMap.put(KeyStroke.getKeyStroke("KP_UP"), highlightPreviousAction);
4632N/A
4632N/A inputMap.put(KeyStroke.getKeyStroke("HOME"), highlightFirstAction);
4632N/A inputMap.put(KeyStroke.getKeyStroke("END"), highlightLastAction);
4632N/A inputMap.put(KeyStroke.getKeyStroke("PAGE_UP"), highlightPageUpAction);
4632N/A inputMap.put(KeyStroke.getKeyStroke("PAGE_DOWN"), highlightPageDownAction);
4632N/A
4632N/A final Action action = getActionMap().get(JTextField.notifyAction);
4632N/A inputMap.put(KeyStroke.getKeyStroke("ENTER"), new AbstractAction() {
4632N/A public void actionPerformed(final ActionEvent e) {
4632N/A if (popup.isVisible()) {
4632N/A triggerSelectionEvent(comboBox, e);
4632N/A
4632N/A if (editor instanceof AquaCustomComboTextField) {
4632N/A ((AquaCustomComboTextField)editor).selectAll();
4632N/A }
4632N/A } else {
4632N/A action.actionPerformed(e);
4632N/A }
4632N/A }
4632N/A });
4632N/A }
4632N/A
4632N/A // workaround for 4530952
4632N/A public void setText(final String s) {
4632N/A if (getText().equals(s)) {
4632N/A return;
4632N/A }
4632N/A super.setText(s);
4632N/A }
4632N/A }
4632N/A
4632N/A /**
4632N/A * This listener hides the popup when the focus is lost. It also repaints
4632N/A * when focus is gained or lost.
4632N/A *
4632N/A * This override is necessary because the Basic L&F for the combo box is working
4632N/A * around a Solaris-only bug that we don't have on Mac OS X. So, remove the lightweight
4632N/A * popup check here. rdar://Problem/3518582
4632N/A */
4632N/A protected FocusListener createFocusListener() {
4632N/A return new BasicComboBoxUI.FocusHandler() {
4632N/A public void focusLost(final FocusEvent e) {
4632N/A hasFocus = false;
4632N/A if (!e.isTemporary()) {
4632N/A setPopupVisible(comboBox, false);
4632N/A }
4632N/A comboBox.repaint();
4632N/A
4632N/A // Notify assistive technologies that the combo box lost focus
4632N/A final AccessibleContext ac = ((Accessible)comboBox).getAccessibleContext();
4632N/A if (ac != null) {
4632N/A ac.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
4632N/A }
4632N/A }
4632N/A };
4632N/A }
4632N/A
4632N/A protected void installKeyboardActions() {
4632N/A super.installKeyboardActions();
4632N/A
4632N/A final ActionMap actionMap = comboBox.getActionMap();
4632N/A actionMap.put("aquaSelectNext", highlightNextAction);
4632N/A actionMap.put("aquaSelectPrevious", highlightPreviousAction);
4632N/A actionMap.put("aquaEnterPressed", triggerSelectionAction);
4632N/A actionMap.put("aquaSpacePressed", toggleSelectionAction);
4632N/A
4632N/A actionMap.put("aquaSelectHome", highlightFirstAction);
4632N/A actionMap.put("aquaSelectEnd", highlightLastAction);
4632N/A actionMap.put("aquaSelectPageUp", highlightPageUpAction);
4632N/A actionMap.put("aquaSelectPageDown", highlightPageDownAction);
4632N/A }
4632N/A
4632N/A abstract class ComboBoxAction extends AbstractAction {
4632N/A public void actionPerformed(final ActionEvent e) {
4632N/A if (!comboBox.isEnabled() || !comboBox.isShowing()) return;
4632N/A
4632N/A if (comboBox.isPopupVisible()) {
4632N/A final AquaComboBoxUI ui = (AquaComboBoxUI)comboBox.getUI();
4632N/A performComboBoxAction(ui);
4632N/A } else {
4632N/A comboBox.setPopupVisible(true);
4632N/A }
4632N/A }
4632N/A
4632N/A abstract void performComboBoxAction(final AquaComboBoxUI ui);
4632N/A }
4632N/A
4632N/A /**
4632N/A * Hilight _but do not select_ the next item in the list.
4632N/A */
4632N/A Action highlightNextAction = new ComboBoxAction() {
4632N/A @Override
4632N/A public void performComboBoxAction(AquaComboBoxUI ui) {
4632N/A final int si = listBox.getSelectedIndex();
4632N/A
4632N/A if (si < comboBox.getModel().getSize() - 1) {
4632N/A listBox.setSelectedIndex(si + 1);
4632N/A listBox.ensureIndexIsVisible(si + 1);
4632N/A }
4632N/A comboBox.repaint();
4632N/A }
4632N/A };
4632N/A
4632N/A /**
4632N/A * Hilight _but do not select_ the previous item in the list.
4632N/A */
4632N/A Action highlightPreviousAction = new ComboBoxAction() {
4632N/A @Override
4632N/A void performComboBoxAction(final AquaComboBoxUI ui) {
4632N/A final int si = listBox.getSelectedIndex();
4632N/A if (si > 0) {
4632N/A listBox.setSelectedIndex(si - 1);
4632N/A listBox.ensureIndexIsVisible(si - 1);
4632N/A }
4632N/A comboBox.repaint();
4632N/A }
4632N/A };
4632N/A
4632N/A Action highlightFirstAction = new ComboBoxAction() {
4632N/A @Override
4632N/A void performComboBoxAction(final AquaComboBoxUI ui) {
4632N/A listBox.setSelectedIndex(0);
4632N/A listBox.ensureIndexIsVisible(0);
4632N/A }
4632N/A };
4632N/A
4632N/A Action highlightLastAction = new ComboBoxAction() {
4632N/A @Override
4632N/A void performComboBoxAction(final AquaComboBoxUI ui) {
4632N/A final int size = listBox.getModel().getSize();
4632N/A listBox.setSelectedIndex(size - 1);
4632N/A listBox.ensureIndexIsVisible(size - 1);
4632N/A }
4632N/A };
4632N/A
4632N/A Action highlightPageUpAction = new ComboBoxAction() {
4632N/A @Override
4632N/A void performComboBoxAction(final AquaComboBoxUI ui) {
4632N/A final int current = listBox.getSelectedIndex();
4632N/A final int first = listBox.getFirstVisibleIndex();
4632N/A
4632N/A if (current != first) {
4632N/A listBox.setSelectedIndex(first);
4632N/A return;
4632N/A }
4632N/A
4632N/A final int page = listBox.getVisibleRect().height / listBox.getCellBounds(0, 0).height;
4632N/A int target = first - page;
4632N/A if (target < 0) target = 0;
4632N/A
4632N/A listBox.ensureIndexIsVisible(target);
4632N/A listBox.setSelectedIndex(target);
4632N/A }
4632N/A };
4632N/A
4632N/A Action highlightPageDownAction = new ComboBoxAction() {
4632N/A @Override
4632N/A void performComboBoxAction(final AquaComboBoxUI ui) {
4632N/A final int current = listBox.getSelectedIndex();
4632N/A final int last = listBox.getLastVisibleIndex();
4632N/A
4632N/A if (current != last) {
4632N/A listBox.setSelectedIndex(last);
4632N/A return;
4632N/A }
4632N/A
4632N/A final int page = listBox.getVisibleRect().height / listBox.getCellBounds(0, 0).height;
4632N/A final int end = listBox.getModel().getSize() - 1;
4632N/A int target = last + page;
4632N/A if (target > end) target = end;
4632N/A
4632N/A listBox.ensureIndexIsVisible(target);
4632N/A listBox.setSelectedIndex(target);
4632N/A }
4632N/A };
4632N/A
4632N/A // For <rdar://problem/3759984> Java 1.4.2_5: Serializing Swing components not working
4632N/A // Inner classes were using a this reference and then trying to serialize the AquaComboBoxUI
4632N/A // We shouldn't do that. But we need to be able to get the popup from other classes, so we need
4632N/A // a public accessor.
4632N/A public ComboPopup getPopup() {
4632N/A return popup;
4632N/A }
4632N/A
4632N/A protected LayoutManager createLayoutManager() {
4632N/A return new AquaComboBoxLayoutManager();
4632N/A }
4632N/A
4632N/A class AquaComboBoxLayoutManager extends BasicComboBoxUI.ComboBoxLayoutManager {
4632N/A public void layoutContainer(final Container parent) {
4632N/A if (arrowButton != null && !comboBox.isEditable()) {
4632N/A final Insets insets = comboBox.getInsets();
4632N/A final int width = comboBox.getWidth();
4632N/A final int height = comboBox.getHeight();
4632N/A arrowButton.setBounds(insets.left, insets.top, width - (insets.left + insets.right), height - (insets.top + insets.bottom));
4632N/A return;
4632N/A }
4632N/A
4632N/A final JComboBox cb = (JComboBox)parent;
4632N/A final int width = cb.getWidth();
4632N/A final int height = cb.getHeight();
4632N/A
4632N/A final Insets insets = getInsets();
4632N/A final int buttonHeight = height - (insets.top + insets.bottom);
4632N/A final int buttonWidth = 20;
4632N/A
4632N/A if (arrowButton != null) {
4632N/A arrowButton.setBounds(width - (insets.right + buttonWidth), insets.top, buttonWidth, buttonHeight);
4632N/A }
4632N/A
4632N/A if (editor != null) {
4632N/A final Rectangle editorRect = rectangleForCurrentValue();
4632N/A editorRect.width += 4;
4632N/A editor.setBounds(editorRect);
4632N/A }
4632N/A }
4632N/A }
4632N/A
4632N/A // This is here because Sun can't use protected like they should!
4632N/A protected static final String IS_TABLE_CELL_EDITOR = "JComboBox.isTableCellEditor";
4632N/A
4632N/A protected static boolean isTableCellEditor(final JComponent c) {
4632N/A return Boolean.TRUE.equals(c.getClientProperty(AquaComboBoxUI.IS_TABLE_CELL_EDITOR));
4632N/A }
4632N/A
4632N/A protected static boolean isPopdown(final JComboBox c) {
4632N/A return c.isEditable() || Boolean.TRUE.equals(c.getClientProperty(AquaComboBoxUI.POPDOWN_CLIENT_PROPERTY_KEY));
4632N/A }
4632N/A
4632N/A protected static void triggerSelectionEvent(final JComboBox comboBox, final ActionEvent e) {
4632N/A if (!comboBox.isEnabled()) return;
4632N/A
4632N/A final AquaComboBoxUI aquaUi = (AquaComboBoxUI)comboBox.getUI();
4632N/A
4632N/A if (aquaUi.getPopup().getList().getSelectedIndex() < 0) {
4632N/A comboBox.setPopupVisible(false);
4632N/A }
4632N/A
4632N/A if (isTableCellEditor(comboBox)) {
4632N/A // Forces the selection of the list item if the combo box is in a JTable
4632N/A comboBox.setSelectedIndex(aquaUi.getPopup().getList().getSelectedIndex());
4632N/A return;
4632N/A }
4632N/A
4632N/A if (comboBox.isPopupVisible()) {
4632N/A comboBox.setSelectedIndex(aquaUi.getPopup().getList().getSelectedIndex());
4632N/A comboBox.setPopupVisible(false);
4632N/A return;
4632N/A }
4632N/A
4632N/A // Call the default button binding.
4632N/A // This is a pretty messy way of passing an event through to the root pane
4632N/A final JRootPane root = SwingUtilities.getRootPane(comboBox);
4632N/A if (root == null) return;
4632N/A
4632N/A final InputMap im = root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
4632N/A final ActionMap am = root.getActionMap();
4632N/A if (im == null || am == null) return;
4632N/A
4632N/A final Object obj = im.get(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
4632N/A if (obj == null) return;
4632N/A
4632N/A final Action action = am.get(obj);
4632N/A if (action == null) return;
4632N/A
4632N/A action.actionPerformed(new ActionEvent(root, e.getID(), e.getActionCommand(), e.getWhen(), e.getModifiers()));
4632N/A }
4632N/A
4632N/A // This is somewhat messy. The difference here from BasicComboBoxUI.EnterAction is that
4632N/A // arrow up or down does not automatically select the
4632N/A static final Action triggerSelectionAction = new AbstractAction() {
4632N/A public void actionPerformed(final ActionEvent e) {
4632N/A triggerSelectionEvent((JComboBox)e.getSource(), e);
4632N/A }
4632N/A };
4632N/A
4632N/A static final Action toggleSelectionAction = new AbstractAction() {
4632N/A public void actionPerformed(final ActionEvent e) {
4632N/A final JComboBox comboBox = (JComboBox)e.getSource();
4632N/A if (!comboBox.isEnabled()) return;
4632N/A if (comboBox.isEditable()) return;
4632N/A
4632N/A final AquaComboBoxUI aquaUi = (AquaComboBoxUI)comboBox.getUI();
4632N/A
4632N/A if (comboBox.isPopupVisible()) {
4632N/A comboBox.setSelectedIndex(aquaUi.getPopup().getList().getSelectedIndex());
4632N/A comboBox.setPopupVisible(false);
4632N/A return;
4632N/A }
4632N/A
4632N/A comboBox.setPopupVisible(true);
4632N/A }
4632N/A };
4632N/A
4632N/A public void applySizeFor(final JComponent c, final Size size) {
4632N/A if (arrowButton == null) return;
4632N/A final Border border = arrowButton.getBorder();
4632N/A if (!(border instanceof AquaButtonBorder)) return;
4632N/A final AquaButtonBorder aquaBorder = (AquaButtonBorder)border;
4632N/A arrowButton.setBorder(aquaBorder.deriveBorderForSize(size));
4632N/A }
4632N/A
4632N/A public Dimension getMinimumSize(final JComponent c) {
4632N/A if (!isMinimumSizeDirty) {
4632N/A return new Dimension(cachedMinimumSize);
4632N/A }
4632N/A
4632N/A final boolean editable = comboBox.isEditable();
4632N/A
4632N/A final Dimension size;
4632N/A if (!editable && arrowButton != null && arrowButton instanceof AquaComboBoxButton) {
4632N/A final AquaComboBoxButton button = (AquaComboBoxButton)arrowButton;
4632N/A final Insets buttonInsets = button.getInsets();
4632N/A // Insets insets = comboBox.getInsets();
4632N/A final Insets insets = new Insets(0, 5, 0, 25);//comboBox.getInsets();
4632N/A
4632N/A size = getDisplaySize();
4632N/A size.width += insets.left + insets.right;
4632N/A size.width += buttonInsets.left + buttonInsets.right;
4632N/A size.width += buttonInsets.right + 10;
4632N/A size.height += insets.top + insets.bottom;
4632N/A size.height += buttonInsets.top + buttonInsets.bottom;
4632N/A // Min height = Height of arrow button plus 2 pixels fuzz above plus 2 below. 23 + 2 + 2
4632N/A size.height = Math.max(27, size.height);
4632N/A } else if (editable && arrowButton != null && editor != null) {
4632N/A size = super.getMinimumSize(c);
4632N/A final Insets margin = arrowButton.getMargin();
4632N/A size.height += margin.top + margin.bottom;
4632N/A } else {
4632N/A size = super.getMinimumSize(c);
4632N/A }
4632N/A
4632N/A final Border border = c.getBorder();
4632N/A if (border != null) {
4632N/A final Insets insets = border.getBorderInsets(c);
4632N/A size.height += insets.top + insets.bottom;
4632N/A size.width += insets.left + insets.right;
4632N/A }
4632N/A
4632N/A cachedMinimumSize.setSize(size.width, size.height);
4632N/A isMinimumSizeDirty = false;
4632N/A
4632N/A return new Dimension(cachedMinimumSize);
4632N/A }
4632N/A
4632N/A @SuppressWarnings("unchecked")
4632N/A static final RecyclableSingleton<ClientPropertyApplicator<JComboBox, AquaComboBoxUI>> APPLICATOR = new RecyclableSingleton<ClientPropertyApplicator<JComboBox, AquaComboBoxUI>>() {
4632N/A @Override
4632N/A protected ClientPropertyApplicator<JComboBox, AquaComboBoxUI> getInstance() {
4632N/A return new ClientPropertyApplicator<JComboBox, AquaComboBoxUI>(
4632N/A new Property<AquaComboBoxUI>(AquaFocusHandler.FRAME_ACTIVE_PROPERTY) {
4632N/A public void applyProperty(final AquaComboBoxUI target, final Object value) {
4632N/A if (Boolean.FALSE.equals(value)) {
4632N/A if (target.comboBox != null) target.comboBox.hidePopup();
4632N/A }
4632N/A if (target.listBox != null) target.listBox.repaint();
4632N/A }
4632N/A },
4632N/A new Property<AquaComboBoxUI>("editable") {
4632N/A public void applyProperty(final AquaComboBoxUI target, final Object value) {
4632N/A if (target.comboBox == null) return;
4632N/A target.comboBox.repaint();
4632N/A }
4632N/A },
4632N/A new Property<AquaComboBoxUI>("background") {
4632N/A public void applyProperty(final AquaComboBoxUI target, final Object value) {
4632N/A final Color color = (Color)value;
4632N/A if (target.arrowButton != null) target.arrowButton.setBackground(color);
4632N/A if (target.listBox != null) target.listBox.setBackground(color);
4632N/A }
4632N/A },
4632N/A new Property<AquaComboBoxUI>("foreground") {
4632N/A public void applyProperty(final AquaComboBoxUI target, final Object value) {
4632N/A final Color color = (Color)value;
4632N/A if (target.arrowButton != null) target.arrowButton.setForeground(color);
4632N/A if (target.listBox != null) target.listBox.setForeground(color);
4632N/A }
4632N/A },
4632N/A new Property<AquaComboBoxUI>(POPDOWN_CLIENT_PROPERTY_KEY) {
4632N/A public void applyProperty(final AquaComboBoxUI target, final Object value) {
4632N/A if (!(target.arrowButton instanceof AquaComboBoxButton)) return;
4632N/A ((AquaComboBoxButton)target.arrowButton).setIsPopDown(Boolean.TRUE.equals(value));
4632N/A }
4632N/A },
4632N/A new Property<AquaComboBoxUI>(ISSQUARE_CLIENT_PROPERTY_KEY) {
4632N/A public void applyProperty(final AquaComboBoxUI target, final Object value) {
4632N/A if (!(target.arrowButton instanceof AquaComboBoxButton)) return;
4632N/A ((AquaComboBoxButton)target.arrowButton).setIsSquare(Boolean.TRUE.equals(value));
4632N/A }
4632N/A }
4632N/A ) {
4632N/A public AquaComboBoxUI convertJComponentToTarget(final JComboBox combo) {
4632N/A final ComboBoxUI comboUI = combo.getUI();
4632N/A if (comboUI instanceof AquaComboBoxUI) return (AquaComboBoxUI)comboUI;
4632N/A return null;
4632N/A }
4632N/A };
4632N/A }
4632N/A };
4632N/A static ClientPropertyApplicator<JComboBox, AquaComboBoxUI> getApplicator() {
4632N/A return APPLICATOR.get();
4632N/A }
4632N/A}