/* * @(#)QuaquaComboBoxButton.java * * Copyright (c) 2004-2010 Werner Randelshofer, Immensee, Switzerland. * All rights reserved. * * You may not use, copy or modify this file, except in compliance with the * license agreement you entered into with Werner Randelshofer. * For details see accompanying license terms. */ package ch.randelshofer.quaqua; import ch.randelshofer.quaqua.border.ButtonStateBorder; import java.awt.*; import javax.swing.CellRendererPane; import javax.swing.DefaultButtonModel; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; import javax.swing.UIManager; import javax.swing.border.Border; import ch.randelshofer.quaqua.util.Images; /** * JButton subclass to help out QuaquaComboBoxUI. * * @author Werner Randelshofer * @version $Id: QuaquaComboBoxButton.java 416 2011-07-30 14:12:52Z wrandelshofer $ */ public class QuaquaComboBoxButton extends JButton { protected JComboBox comboBox; protected JList listBox; protected CellRendererPane rendererPane; protected Icon comboIcon; protected boolean iconOnly = false; /** * This is the focus border painted around the button when it has focus. */ private static Border focusRing; private static Border getFocusRing() { if (focusRing == null) { focusRing = QuaquaBorderFactory.create( Images.createImage(QuaquaComboBoxButton.class.getResource("images/ComboBox.focusRing.png")), new Insets(4, 6, 4, 6), new Insets(0, 0, 0, 0), false); } return focusRing; } /** * This is the border painted around the cell area. */ private static Border getCellBorder() { return UIManager.getBorder("ComboBox.cellBorder"); } /** * This is the border painted around the button area. */ private Border getButtonBorder() { switch (QuaquaUtilities.getSizeVariant(comboBox)) { default: return UIManager.getBorder("ComboBox.buttonBorder"); case SMALL: return UIManager.getBorder("ComboBox.smallButtonBorder"); case MINI: return UIManager.getBorder("ComboBox.miniButtonBorder"); } } /** * This is the border painted around the cell area. */ private static Border getSmallCellBorder() { return UIManager.getBorder("ComboBox.smallCellBorder"); } /** * This is the border painted around the button area. */ private static Border getSmallButtonBorder() { return UIManager.getBorder("ComboBox.smallButtonBorder"); } public final JComboBox getComboBox() { return comboBox; } public final void setComboBox(JComboBox cb) { comboBox = cb; } public final Icon getComboIcon() { return comboIcon; } public final void setComboIcon(Icon i) { comboIcon = i; } public final boolean isIconOnly() { return iconOnly; } public final void setIconOnly(boolean isIconOnly) { iconOnly = isIconOnly; } //QuaquaComboBoxButton() { public QuaquaComboBoxButton(QuaquaComboBoxUI ui, JComboBox cb, Icon i, boolean onlyIcon, CellRendererPane pane, JList list) { super(""); DefaultButtonModel model = new DefaultButtonModel() { @Override public void setArmed(boolean armed) { super.setArmed(isPressed() ? true : armed); } }; setModel(model); setBorder(null); // We do all the border handling in QuaquaComboBoxUI comboBox = cb; comboIcon = i; rendererPane = pane; listBox = list; setEnabled(comboBox.isEnabled()); iconOnly = onlyIcon; } @Override public boolean isFocusTraversable() { return false; } @Override public void setBorder(Border b) { // Empty. We do all border handling in QuaquaComboBoxUI } /* public boolean isOpaque() { return false; }*/ @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); // Set the background and foreground to the combobox colors. if (enabled) { setBackground(comboBox.getBackground()); setForeground(comboBox.getForeground()); } else { setBackground(UIManager.getColor("ComboBox.disabledBackground")); setForeground(UIManager.getColor("ComboBox.disabledForeground")); } } @Override public void paintBorder(Graphics g) { // Empty: We paint the border in paintComponent. } @Override public void paintComponent(Graphics g) { Object savedHints = QuaquaUtilities.beginGraphics((Graphics2D) g); QuaquaComboBoxUI ui = (QuaquaComboBoxUI) comboBox.getUI(); int buttonWidth = ui.getArrowWidth(); boolean isTableCellEditor = ui.isTableCellEditor(); QuaquaUtilities.SizeVariant sizeVariant = QuaquaUtilities.getSizeVariant(comboBox); boolean isSmall = sizeVariant == QuaquaUtilities.SizeVariant.SMALL; Insets insets = getInsets(); // Paint background and borders int x, y, width, height; x = insets.left; y = insets.top; width = getWidth() - insets.left - insets.right; height = getHeight() - insets.top - insets.bottom; if (comboBox.isOpaque()) { g.setColor(comboBox.getBackground()); g.fillRect(0, 0, width, height); } if (!isTableCellEditor) { if (iconOnly) { Border border = getButtonBorder(); if (border != null) { border.paintBorder(this, g, x, y, width, height); } } else { Border border; switch (sizeVariant) { case SMALL: border = UIManager.getBorder("ComboBox.smallCellAndButtonBorder"); break; case MINI: border = UIManager.getBorder("ComboBox.miniCellAndButtonBorder"); break; default: border = UIManager.getBorder("ComboBox.cellAndButtonBorder"); break; } if (border != null) { border.paintBorder(this, g, x, y, width, height); } else { // this code is used by the non-native versions of Quaqua. border = (isSmall) ? getSmallCellBorder() : getCellBorder(); if (border != null) { border.paintBorder(this, g, x, y, width - buttonWidth, height); } border = (isSmall) ? getSmallButtonBorder() : getButtonBorder(); if (border != null) { border.paintBorder(this, g, width - buttonWidth, y, buttonWidth, height); } } } } boolean leftToRight = QuaquaUtilities.isLeftToRight(comboBox); // Paint the icon comboIcon = ui.getArrowIcon(); if (comboIcon != null) { int iconWidth = comboIcon.getIconWidth(); int iconHeight = comboIcon.getIconHeight(); int iconTop = 0; int iconLeft = 0; if (iconOnly) { iconLeft = x + (width - buttonWidth) / 2 + (buttonWidth - iconWidth) / 2 - 2; iconTop = y + (height - iconHeight) / 2; } else { if (leftToRight) { iconLeft = x + width - buttonWidth + (buttonWidth - iconWidth) / 2 - 1; } else { iconLeft = 0; } iconTop = y + (height - iconHeight) / 2; //if (isSmallSizeVariant) iconTop--; } comboIcon.paintIcon(this, g, iconLeft, iconTop); // Paint the focus if (QuaquaUtilities.isFocused(comboBox) && !isTableCellEditor) { Border border = null; border = getFocusRing(); if (border != null) { border.paintBorder(this, g, x, y, width, height); } } } // Let the renderer paint if (!iconOnly && comboBox != null) { ListCellRenderer renderer = comboBox.getRenderer(); Component c; boolean renderPressed = getModel().isPressed(); c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, renderPressed, false); c.setFont(comboBox.getFont()); c.setEnabled(comboBox.isEnabled()); Rectangle cellBounds = ((QuaquaComboBoxUI) comboBox.getUI()).rectangleForCurrentValue(); // Fix for 4238829: should lay out the JPanel. boolean shouldValidate = false; if (c instanceof JPanel) { shouldValidate = true; } boolean wasOpaque = c.isOpaque(); if (c instanceof JComponent) { ((JComponent) c).setOpaque(false); } if (leftToRight) { rendererPane.paintComponent(g, c, this, cellBounds.x - getX(), cellBounds.y - getY(), cellBounds.width, cellBounds.height, shouldValidate); } else { rendererPane.paintComponent(g, c, this, cellBounds.x, cellBounds.y, cellBounds.width, cellBounds.height, shouldValidate); } if (c instanceof JComponent) { ((JComponent) c).setOpaque(wasOpaque); } } QuaquaUtilities.endGraphics((Graphics2D) g, savedHints); } }