Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxRendererInternal.java
38831 views
/*1* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.apple.laf;2627import sun.swing.SwingUtilities2;2829import javax.swing.*;30import java.awt.*;3132class AquaComboBoxRendererInternal extends JLabel implements ListCellRenderer {33final JComboBox fComboBox;34boolean fSelected;35boolean fChecked;36boolean fInList;37boolean fEditable;38boolean fDrawCheckedItem = true;3940// Provides space for a checkbox, and is translucent41public AquaComboBoxRendererInternal(final JComboBox comboBox) {42super();43fComboBox = comboBox;44}4546// Don't include checkIcon space, because this is also used for button size calculations47// - the popup-size calc will get checkIcon space from getInsets48public Dimension getPreferredSize() {49// From BasicComboBoxRenderer - trick to avoid zero-height items50final Dimension size;5152final String text = getText();53if ((text == null) || ("".equals(text))) {54setText(" ");55size = super.getPreferredSize();56setText("");57} else {58size = super.getPreferredSize();59}60return size;61}6263// Don't paint the border here, it gets painted by the UI64protected void paintBorder(final Graphics g) {6566}6768public int getBaseline(int width, int height) {69return super.getBaseline(width, height) - 1;70}7172// Really means is the one with the mouse over it73public Component getListCellRendererComponent(final JList list, final Object value, int index, final boolean isSelected, final boolean cellHasFocus) {74fInList = (index >= 0); // When the button wants the item painted, it passes in -175fSelected = isSelected;76if (index < 0) {77index = fComboBox.getSelectedIndex();78}7980// changed this to not ask for selected index but directly compare the current item and selected item81// different from basic because basic has no concept of checked, just has the last one selected,82// and the user changes selection. We have selection and a check mark.83// we used to call fComboBox.getSelectedIndex which ends up being a very bad call for large checkboxes84// it does a linear compare of every object in the checkbox until it finds the selected one, so if85// we have a 5000 element list we will 5000 * (selected index) .equals() of objects.86// See Radar #31413078788// Fix for Radar # 3204287 where we ask for an item at a negative index!89if (index >= 0) {90final Object item = fComboBox.getItemAt(index);91fChecked = fInList && item != null && item.equals(fComboBox.getSelectedItem());92} else {93fChecked = false;94}9596fEditable = fComboBox.isEditable();97if (isSelected) {98if (fEditable) {99setBackground(UIManager.getColor("List.selectionBackground"));100setForeground(UIManager.getColor("List.selectionForeground"));101} else {102setBackground(list.getSelectionBackground());103setForeground(list.getSelectionForeground());104}105} else {106if (fEditable) {107setBackground(UIManager.getColor("List.background"));108setForeground(UIManager.getColor("List.foreground"));109} else {110setBackground(list.getBackground());111setForeground(list.getForeground());112}113}114115setFont(list.getFont());116117if (value instanceof Icon) {118setIcon((Icon)value);119} else {120setText((value == null) ? " " : value.toString());121}122return this;123}124125public Insets getInsets(Insets insets) {126if (insets == null) insets = new Insets(0, 0, 0, 0);127insets.top = 1;128insets.bottom = 1;129insets.right = 5;130insets.left = (fInList && !fEditable ? 16 + 7 : 5);131return insets;132}133134protected void setDrawCheckedItem(final boolean drawCheckedItem) {135this.fDrawCheckedItem = drawCheckedItem;136}137138// Paint this component, and a checkbox if it's the selected item and not in the button139protected void paintComponent(final Graphics g) {140if (fInList) {141if (fSelected && !fEditable) {142AquaMenuPainter.instance().paintSelectedMenuItemBackground(g, getWidth(), getHeight());143} else {144g.setColor(getBackground());145g.fillRect(0, 0, getWidth(), getHeight());146}147148if (fChecked && !fEditable && fDrawCheckedItem) {149final int y = getHeight() - 4;150g.setColor(getForeground());151SwingUtilities2.drawString(fComboBox, g, "\u2713", 6, y);152}153}154super.paintComponent(g);155}156}157158159