| /* |
| * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.apple.laf; |
| |
| import java.awt.*; |
| |
| import javax.swing.*; |
| import javax.swing.plaf.UIResource; |
| |
| import apple.laf.JRSUIState; |
| import apple.laf.JRSUIConstants.*; |
| |
| @SuppressWarnings("serial") // Superclass is not serializable across versions |
| class AquaComboBoxButton extends JButton { |
| protected final JComboBox<Object> comboBox; |
| protected final JList<?> list; |
| protected final CellRendererPane rendererPane; |
| protected final AquaComboBoxUI ui; |
| |
| protected final AquaPainter<JRSUIState> painter = AquaPainter.create(JRSUIState.getInstance()); |
| boolean isPopDown; |
| boolean isSquare; |
| |
| @SuppressWarnings("serial") // anonymous class |
| protected AquaComboBoxButton(final AquaComboBoxUI ui, |
| final JComboBox<Object> comboBox, |
| final CellRendererPane rendererPane, |
| final JList<?> list) { |
| super(""); |
| putClientProperty("JButton.buttonType", "comboboxInternal"); |
| |
| this.ui = ui; |
| this.comboBox = comboBox; |
| this.rendererPane = rendererPane; |
| this.list = list; |
| |
| setModel(new DefaultButtonModel() { |
| @Override |
| public void setArmed(final boolean armed) { |
| super.setArmed(isPressed() ? true : armed); |
| } |
| }); |
| |
| setEnabled(comboBox.isEnabled()); |
| } |
| |
| @Override |
| public boolean isEnabled() { |
| return comboBox == null ? true : comboBox.isEnabled(); |
| } |
| |
| @Override |
| public boolean isFocusable() { |
| return false; |
| } |
| |
| protected void setIsPopDown(final boolean isPopDown) { |
| this.isPopDown = isPopDown; |
| repaint(); |
| } |
| |
| protected void setIsSquare(final boolean isSquare) { |
| this.isSquare = isSquare; |
| repaint(); |
| } |
| |
| protected State getState(final ButtonModel buttonModel) { |
| if (!comboBox.isEnabled()) return State.DISABLED; |
| if (!AquaFocusHandler.isActive(comboBox)) return State.INACTIVE; |
| if (buttonModel.isArmed()) return State.PRESSED; |
| return State.ACTIVE; |
| } |
| |
| @Override |
| public void paintComponent(final Graphics g) { |
| // Don't Paint the button as usual |
| // super.paintComponent( g ); |
| final boolean editable = comboBox.isEditable(); |
| |
| int top = 0; |
| int left = 0; |
| int width = getWidth(); |
| int height = getHeight(); |
| |
| if (comboBox.isOpaque()) { |
| g.setColor(getBackground()); |
| g.fillRect(0, 0, width, height); |
| } |
| |
| final Size size = AquaUtilControlSize.getUserSizeFrom(comboBox); |
| painter.state.set(size == null ? Size.REGULAR : size); |
| |
| final ButtonModel buttonModel = getModel(); |
| painter.state.set(getState(buttonModel)); |
| |
| painter.state.set(AlignmentVertical.CENTER); |
| |
| if (AquaComboBoxUI.isTableCellEditor(comboBox)) { |
| painter.state.set(AlignmentHorizontal.RIGHT); |
| painter.state.set(Widget.BUTTON_POP_UP); |
| painter.state.set(ArrowsOnly.YES); |
| painter.paint(g, this, left, top, width, height); |
| doRendererPaint(g, buttonModel, editable, getInsets(), left, top, width, height); |
| return; |
| } |
| |
| painter.state.set(AlignmentHorizontal.CENTER); |
| final Insets insets = getInsets(); |
| if (!editable) { |
| top += insets.top; |
| left += insets.left; |
| width -= insets.left + insets.right; |
| height -= insets.top + insets.bottom; |
| } |
| |
| if (height <= 0 || width <= 0) { |
| return; |
| } |
| |
| boolean hasFocus = comboBox.hasFocus(); |
| if (editable) { |
| painter.state.set(Widget.BUTTON_COMBO_BOX); |
| painter.state.set(IndicatorOnly.YES); |
| painter.state.set(AlignmentHorizontal.LEFT); |
| hasFocus |= comboBox.getEditor().getEditorComponent().hasFocus(); |
| } else { |
| painter.state.set(IndicatorOnly.NO); |
| painter.state.set(AlignmentHorizontal.CENTER); |
| if (isPopDown) { |
| painter.state.set(isSquare ? Widget.BUTTON_POP_DOWN_SQUARE : Widget.BUTTON_POP_DOWN); |
| } else { |
| painter.state.set(isSquare ? Widget.BUTTON_POP_UP_SQUARE : Widget.BUTTON_POP_UP); |
| } |
| } |
| painter.state.set(hasFocus ? Focused.YES : Focused.NO); |
| |
| if (isSquare) { |
| painter.paint(g, comboBox, left + 2, top - 1, width - 4, height); |
| } else { |
| painter.paint(g, comboBox, left, top, width, height); |
| } |
| |
| // Let the renderer paint |
| if (!editable && comboBox != null) { |
| doRendererPaint(g, buttonModel, editable, insets, left, top, width, height); |
| } |
| } |
| |
| protected void doRendererPaint(final Graphics g, final ButtonModel buttonModel, final boolean editable, final Insets insets, int left, int top, int width, int height) { |
| final ListCellRenderer<Object> renderer = comboBox.getRenderer(); |
| |
| // fake it out! not renderPressed |
| final Component c = renderer.getListCellRendererComponent(list, comboBox.getSelectedItem(), -1, false, false); |
| // System.err.println("Renderer: " + renderer); |
| |
| if (!editable && !AquaComboBoxUI.isTableCellEditor(comboBox)) { |
| final int indentLeft = 10; |
| final int buttonWidth = 24; |
| |
| // hardcoded for now. We should adjust as necessary. |
| top += 1; |
| height -= 4; |
| left += indentLeft; |
| width -= (indentLeft + buttonWidth); |
| } |
| |
| c.setFont(rendererPane.getFont()); |
| |
| if (buttonModel.isArmed() && buttonModel.isPressed()) { |
| if (isOpaque()) { |
| c.setBackground(UIManager.getColor("Button.select")); |
| } |
| c.setForeground(comboBox.getForeground()); |
| } else if (!comboBox.isEnabled()) { |
| if (isOpaque()) { |
| c.setBackground(UIManager.getColor("ComboBox.disabledBackground")); |
| } |
| c.setForeground(UIManager.getColor("ComboBox.disabledForeground")); |
| } else { |
| c.setForeground(comboBox.getForeground()); |
| c.setBackground(comboBox.getBackground()); |
| } |
| |
| // Sun Fix for 4238829: should lay out the JPanel. |
| boolean shouldValidate = false; |
| if (c instanceof JPanel) { |
| shouldValidate = true; |
| } |
| |
| final int iconWidth = 0; |
| final int cWidth = width - (insets.right + iconWidth); |
| |
| // fix for 3156483 we need to crop images that are too big. |
| // if (height > 18) |
| // always crop. |
| { |
| top = height / 2 - 8; |
| height = 19; |
| } |
| |
| // It doesn't need to draw its background, we handled it |
| final Color bg = c.getBackground(); |
| final boolean inhibitBackground = bg instanceof UIResource; |
| if (inhibitBackground) c.setBackground(new Color(0, 0, 0, 0)); |
| |
| rendererPane.paintComponent(g, c, this, left, top, cWidth, height, shouldValidate); // h - (insets.top + insets.bottom) ); |
| |
| if (inhibitBackground) c.setBackground(bg); |
| } |
| } |