/* * 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 comboBox; protected final JList list; protected final CellRendererPane rendererPane; protected final AquaComboBoxUI ui; protected final AquaPainter painter = AquaPainter.create(JRSUIState.getInstance()); boolean isPopDown; boolean isSquare; @SuppressWarnings("serial") // anonymous class protected AquaComboBoxButton(final AquaComboBoxUI ui, final JComboBox 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 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); } }