org.pushingpixels.flamingo.internal.ui.common.BasicCommandButtonUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of flamengo Show documentation
Show all versions of flamengo Show documentation
Flamingo Swing component suite
The newest version!
/*
* Copyright (c) 2005-2010 Flamingo Kirill Grouchnikov. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of Flamingo Kirill Grouchnikov nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.pushingpixels.flamingo.internal.ui.common;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.ColorConvertOp;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import org.pushingpixels.flamingo.api.common.*;
import org.pushingpixels.flamingo.api.common.CommandButtonLayoutManager.CommandButtonLayoutInfo;
import org.pushingpixels.flamingo.api.common.CommandButtonLayoutManager.CommandButtonSeparatorOrientation;
import org.pushingpixels.flamingo.api.common.JCommandButtonStrip.StripOrientation;
import org.pushingpixels.flamingo.api.common.icon.FilteredResizableIcon;
import org.pushingpixels.flamingo.api.common.icon.ResizableIcon;
import org.pushingpixels.flamingo.api.common.model.PopupButtonModel;
import org.pushingpixels.flamingo.api.common.popup.*;
import org.pushingpixels.flamingo.internal.utils.*;
/**
* Basic UI for command button {@link JCommandButton}.
*
* @author Kirill Grouchnikov
*/
public class BasicCommandButtonUI extends CommandButtonUI {
/**
* The associated command button.
*/
protected AbstractCommandButton commandButton;
/**
* Indication whether the mouse pointer is over the associated command
* button.
*/
protected boolean isUnderMouse;
/**
* Property change listener.
*/
protected PropertyChangeListener propertyChangeListener;
/**
* Tracks user interaction with the command button (including keyboard and
* mouse).
*/
protected BasicCommandButtonListener basicPopupButtonListener;
/**
* Layout information.
*/
protected CommandButtonLayoutManager.CommandButtonLayoutInfo layoutInfo;
/**
* Client property to mark the command button to have square corners. This
* client property is for internal use only.
*/
public static final String EMULATE_SQUARE_BUTTON = "flamingo.internal.commandButton.ui.emulateSquare";
/**
* Client property to mark the command button to not dispose the popups on
* activation.
*
* @see #disposePopupsActionListener
*/
public static final String DONT_DISPOSE_POPUPS = "flamingo.internal.commandButton.ui.dontDisposePopups";
/**
* This listener disposes all popup panels when button's action is
* activated. An example of scenario would be a command button in the popup
* panel of an in-ribbon gallery. When this command button is activated, the
* associated popup panel is dismissed.
*
* @see #DONT_DISPOSE_POPUPS
*/
protected ActionListener disposePopupsActionListener;
/**
* Action listener on the popup area.
*/
protected PopupActionListener popupActionListener;
/**
* The "expand" action icon.
*/
protected ResizableIcon popupActionIcon;
protected CommandButtonLayoutManager layoutManager;
/**
* Used to provide a LAF-consistent appearance under core LAFs.
*/
protected CellRendererPane buttonRendererPane;
/**
* Used to provide a LAF-consistent appearance under core LAFs.
*/
protected AbstractButton rendererButton;
/**
* Used to paint the separator between the action and popup areas.
*/
protected JSeparator rendererSeparator;
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
*/
public static ComponentUI createUI(JComponent c) {
return new BasicCommandButtonUI();
}
/**
* Creates a new UI delegate.
*/
public BasicCommandButtonUI() {
// this.toTakeSavedDimension = false;
}
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.ComponentUI#installUI(javax.swing.JComponent)
*/
@Override
public void installUI(JComponent c) {
this.commandButton = (AbstractCommandButton) c;
installDefaults();
installComponents();
installListeners();
installKeyboardActions();
this.layoutManager = this.commandButton.getDisplayState()
.createLayoutManager(this.commandButton);
this.updateCustomDimension();
}
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.ComponentUI#uninstallUI(javax.swing.JComponent)
*/
@Override
public void uninstallUI(JComponent c) {
c.setLayout(null);
uninstallKeyboardActions();
uninstallListeners();
uninstallComponents();
uninstallDefaults();
this.commandButton = null;
}
/**
* Installs defaults on the associated command button.
*/
protected void installDefaults() {
configureRenderer();
this.updateBorder();
this.syncDisabledIcon();
}
protected void configureRenderer() {
this.buttonRendererPane = new CellRendererPane();
this.commandButton.add(buttonRendererPane);
this.rendererButton = createRendererButton();
this.rendererButton.setOpaque(false);
this.rendererSeparator = new JSeparator();
Font currFont = this.commandButton.getFont();
if ((currFont == null) || (currFont instanceof UIResource)) {
this.commandButton.setFont(this.rendererButton.getFont());
}
// special handling for Mac OS X native look-and-feel
this.rendererButton.putClientProperty("JButton.buttonType", "square");
}
protected void updateBorder() {
Border currBorder = this.commandButton.getBorder();
if ((currBorder == null) || (currBorder instanceof UIResource)) {
int tb = (int) (this.commandButton.getVGapScaleFactor() * 4);
int lr = (int) (this.commandButton.getHGapScaleFactor() * 6);
this.commandButton
.setBorder(new BorderUIResource.EmptyBorderUIResource(tb,
lr, tb, lr));
}
}
/**
* Creates the renderer button.
*
* @return The renderer button.
*/
protected AbstractButton createRendererButton() {
return new JButton("");
}
/**
* Installs subcomponents on the associated command button.
*/
protected void installComponents() {
this.updatePopupActionIcon();
ResizableIcon buttonIcon = this.commandButton.getIcon();
if (buttonIcon instanceof AsynchronousLoading) {
((AsynchronousLoading) buttonIcon)
.addAsynchronousLoadListener(new AsynchronousLoadListener() {
public void completed(boolean success) {
if (success && (commandButton != null))
commandButton.repaint();
}
});
}
if (this.commandButton instanceof JCommandButton) {
this.popupActionIcon = this.createPopupActionIcon();
}
}
/**
* Installs listeners on the associated command button.
*/
protected void installListeners() {
this.basicPopupButtonListener = createButtonListener(this.commandButton);
if (this.basicPopupButtonListener != null) {
this.commandButton.addMouseListener(this.basicPopupButtonListener);
this.commandButton
.addMouseMotionListener(this.basicPopupButtonListener);
this.commandButton.addFocusListener(this.basicPopupButtonListener);
this.commandButton.addChangeListener(this.basicPopupButtonListener);
}
this.propertyChangeListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (AbstractButton.ICON_CHANGED_PROPERTY.equals(evt
.getPropertyName())) {
Icon newIcon = (Icon) evt.getNewValue();
if (newIcon instanceof AsynchronousLoading) {
AsynchronousLoading async = (AsynchronousLoading) newIcon;
async
.addAsynchronousLoadListener(new AsynchronousLoadListener() {
public void completed(boolean success) {
if (success) {
if (commandButton != null) {
syncIconDimension();
syncDisabledIcon();
commandButton.repaint();
}
}
}
});
if (!async.isLoading()) {
syncIconDimension();
syncDisabledIcon();
commandButton.repaint();
}
} else {
syncIconDimension();
syncDisabledIcon();
commandButton.revalidate();
commandButton.repaint();
}
}
if ("commandButtonKind".equals(evt.getPropertyName())) {
updatePopupActionIcon();
}
if ("popupOrientationKind".equals(evt.getPropertyName())) {
updatePopupActionIcon();
}
if ("customDimension".equals(evt.getPropertyName())) {
updateCustomDimension();
}
if ("hgapScaleFactor".equals(evt.getPropertyName())) {
updateBorder();
}
if ("vgapScaleFactor".equals(evt.getPropertyName())) {
updateBorder();
}
if ("popupModel".equals(evt.getPropertyName())) {
// rewire the popup action listener on the new popup model
PopupButtonModel oldModel = (PopupButtonModel) evt
.getOldValue();
PopupButtonModel newModel = (PopupButtonModel) evt
.getNewValue();
if (oldModel != null) {
oldModel.removePopupActionListener(popupActionListener);
popupActionListener = null;
}
if (newModel != null) {
popupActionListener = createPopupActionListener();
newModel.addPopupActionListener(popupActionListener);
}
}
if ("displayState".equals(evt.getPropertyName())) {
syncIconDimension();
syncDisabledIcon();
commandButton.invalidate();
commandButton.revalidate();
commandButton.doLayout();
}
// pass the event to the layout manager
if (layoutManager != null) {
layoutManager.propertyChange(evt);
}
if ("componentOrientation".equals(evt.getPropertyName())) {
updatePopupActionIcon();
commandButton.repaint();
}
}
};
this.commandButton
.addPropertyChangeListener(this.propertyChangeListener);
this.disposePopupsActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean toDismiss = !Boolean.TRUE.equals(commandButton
.getClientProperty(DONT_DISPOSE_POPUPS));
if (toDismiss) {
JCommandPopupMenu menu = (JCommandPopupMenu) SwingUtilities
.getAncestorOfClass(JCommandPopupMenu.class,
commandButton);
if (menu != null) {
toDismiss = menu.isToDismissOnChildClick();
}
}
if (toDismiss) {
if (SwingUtilities.getAncestorOfClass(JPopupPanel.class,
commandButton) != null) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// command button may be cleared if the
// button click resulted in LAF switch
if (commandButton != null) {
// clear the active states
commandButton.getActionModel().setPressed(
false);
commandButton.getActionModel().setRollover(
false);
commandButton.getActionModel().setArmed(
false);
}
}
});
}
PopupPanelManager.defaultManager().hidePopups(null);
}
}
};
this.commandButton.addActionListener(this.disposePopupsActionListener);
if (this.commandButton instanceof JCommandButton) {
this.popupActionListener = this.createPopupActionListener();
((JCommandButton) this.commandButton).getPopupModel()
.addPopupActionListener(this.popupActionListener);
}
}
/**
* Creates the icon for the popup area.
*
* @return The icon for the popup area.
*/
protected ResizableIcon createPopupActionIcon() {
return FlamingoUtilities
.getCommandButtonPopupActionIcon((JCommandButton) this.commandButton);
}
/**
* Creates the button listener for the specified command button.
*
* @param b
* Command button.
* @return The button listener for the specified command button.
*/
protected BasicCommandButtonListener createButtonListener(
AbstractCommandButton b) {
return new BasicCommandButtonListener();
}
/**
* Installs the keyboard actions on the associated command button.
*/
protected void installKeyboardActions() {
if (this.basicPopupButtonListener != null) {
basicPopupButtonListener.installKeyboardActions(this.commandButton);
}
}
/**
* Uninstalls defaults from the associated command button.
*/
protected void uninstallDefaults() {
unconfigureRenderer();
}
protected void unconfigureRenderer() {
if (this.buttonRendererPane != null) {
this.commandButton.remove(this.buttonRendererPane);
}
this.buttonRendererPane = null;
}
/**
* Uninstalls subcomponents from the associated command button.
*/
protected void uninstallComponents() {
}
/**
* Uninstalls listeners from the associated command button.
*/
protected void uninstallListeners() {
if (this.basicPopupButtonListener != null) {
this.commandButton
.removeMouseListener(this.basicPopupButtonListener);
this.commandButton
.removeMouseListener(this.basicPopupButtonListener);
this.commandButton
.removeMouseMotionListener(this.basicPopupButtonListener);
this.commandButton
.removeFocusListener(this.basicPopupButtonListener);
this.commandButton
.removeChangeListener(this.basicPopupButtonListener);
}
this.commandButton
.removePropertyChangeListener(this.propertyChangeListener);
this.propertyChangeListener = null;
this.commandButton
.removeActionListener(this.disposePopupsActionListener);
this.disposePopupsActionListener = null;
if (this.commandButton instanceof JCommandButton) {
((JCommandButton) this.commandButton).getPopupModel()
.removePopupActionListener(this.popupActionListener);
this.popupActionListener = null;
}
}
/**
* Uninstalls the keyboard actions from the associated command button.
*/
protected void uninstallKeyboardActions() {
if (this.basicPopupButtonListener != null) {
this.basicPopupButtonListener
.uninstallKeyboardActions(this.commandButton);
}
}
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.ComponentUI#update(java.awt.Graphics,
* javax.swing.JComponent)
*/
@Override
public void update(Graphics g, JComponent c) {
Graphics2D g2d = (Graphics2D) g.create();
RenderingUtils.installDesktopHints(g2d);
super.update(g2d, c);
g2d.dispose();
}
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.ComponentUI#paint(java.awt.Graphics,
* javax.swing.JComponent)
*/
@Override
public void paint(Graphics g, JComponent c) {
g.setFont(FlamingoUtilities.getFont(commandButton, "Ribbon.font",
"Button.font", "Panel.font"));
this.layoutInfo = this.layoutManager.getLayoutInfo(this.commandButton,
g);
commandButton.putClientProperty("icon.bounds", layoutInfo.iconRect);
if (this.isPaintingBackground()) {
this.paintButtonBackground(g, new Rectangle(0, 0, commandButton
.getWidth(), commandButton.getHeight()));
}
// Graphics2D g2d = (Graphics2D) g.create();
// g2d.setColor(new Color(255, 0, 0, 64));
// if (getActionClickArea() != null) {
// g2d.fill(getActionClickArea());
// }
// g2d.setColor(new Color(0, 0, 255, 64));
// if (getPopupClickArea() != null) {
// g2d.fill(getPopupClickArea());
// }
// g2d.dispose();
if (layoutInfo.iconRect != null) {
this.paintButtonIcon(g, layoutInfo.iconRect);
}
if (layoutInfo.popupActionRect.getWidth() > 0) {
paintPopupActionIcon(g, layoutInfo.popupActionRect);
}
FontMetrics fm = g.getFontMetrics();
boolean isTextPaintedEnabled = commandButton.isEnabled();
if (commandButton instanceof JCommandButton) {
JCommandButton jCommandButton = (JCommandButton) commandButton;
isTextPaintedEnabled = layoutInfo.isTextInActionArea ? jCommandButton
.getActionModel().isEnabled()
: jCommandButton.getPopupModel().isEnabled();
}
g.setColor(getForegroundColor(isTextPaintedEnabled));
if (layoutInfo.textLayoutInfoList != null) {
for (CommandButtonLayoutManager.TextLayoutInfo mainTextLayoutInfo : layoutInfo.textLayoutInfoList) {
if (mainTextLayoutInfo.text != null) {
BasicGraphicsUtils.drawString(g, mainTextLayoutInfo.text,
-1, mainTextLayoutInfo.textRect.x,
mainTextLayoutInfo.textRect.y + fm.getAscent());
}
}
}
if (isTextPaintedEnabled) {
g.setColor(FlamingoUtilities.getColor(Color.gray,
"Label.disabledForeground"));
} else {
g.setColor(FlamingoUtilities.getColor(Color.gray,
"Label.disabledForeground").brighter());
}
if (layoutInfo.extraTextLayoutInfoList != null) {
for (CommandButtonLayoutManager.TextLayoutInfo extraTextLayoutInfo : layoutInfo.extraTextLayoutInfoList) {
if (extraTextLayoutInfo.text != null) {
BasicGraphicsUtils.drawString(g, extraTextLayoutInfo.text,
-1, extraTextLayoutInfo.textRect.x,
extraTextLayoutInfo.textRect.y + fm.getAscent());
}
}
}
if (this.isPaintingSeparators() && (layoutInfo.separatorArea != null)) {
if (layoutInfo.separatorOrientation == CommandButtonSeparatorOrientation.HORIZONTAL) {
this
.paintButtonHorizontalSeparator(g,
layoutInfo.separatorArea);
} else {
this.paintButtonVerticalSeparator(g, layoutInfo.separatorArea);
}
}
// Graphics2D g2d = (Graphics2D) g.create();
//
// g2d.setColor(Color.red);
// g2d.draw(layoutInfo.iconRect);
// g2d.setColor(Color.blue);
// if (layoutInfo.textLayoutInfoList != null) {
// for (CommandButtonLayoutManager.TextLayoutInfo mainTextLayoutInfo :
// layoutInfo.textLayoutInfoList) {
// if (mainTextLayoutInfo.text != null) {
// g2d.draw(mainTextLayoutInfo.textRect);
// }
// }
// }
// g2d.setColor(Color.magenta);
// if (layoutInfo.extraTextLayoutInfoList != null) {
// for (CommandButtonLayoutManager.TextLayoutInfo extraTextLayoutInfo :
// layoutInfo.extraTextLayoutInfoList) {
// if (extraTextLayoutInfo.text != null) {
// g2d.draw(extraTextLayoutInfo.textRect);
// }
// }
// }
// g2d.setColor(Color.green);
// g2d.draw(layoutInfo.popupActionRect);
// g2d.dispose();
}
protected Color getForegroundColor(boolean isTextPaintedEnabled) {
if (isTextPaintedEnabled) {
return FlamingoUtilities.getColor(Color.black, "Button.foreground");
} else {
return FlamingoUtilities.getColor(Color.gray,
"Label.disabledForeground");
}
}
/**
* Paints the icon of the popup area.
*
* @param g
* Graphics context.
* @param popupActionRect
*/
protected void paintPopupActionIcon(Graphics g, Rectangle popupActionRect) {
int size = Math.max(popupActionRect.width - 2, 7);
if (size % 2 == 0)
size--;
popupActionIcon.setDimension(new Dimension(size, size));
popupActionIcon.paintIcon(this.commandButton, g, popupActionRect.x
+ (popupActionRect.width - size) / 2, popupActionRect.y
+ (popupActionRect.height - size) / 2);
}
/**
* Returns the current icon.
*
* @return Current icon.
*/
protected Icon getIconToPaint() {
return (toUseDisabledIcon() && this.commandButton.getDisabledIcon() != null) ? this.commandButton
.getDisabledIcon()
: this.commandButton.getIcon();
}
protected boolean toUseDisabledIcon() {
// special case for command buttons with POPUP_ONLY kind -
// check the popup model
boolean toUseDisabledIcon;
if (this.commandButton instanceof JCommandButton
&& ((JCommandButton) this.commandButton).getCommandButtonKind() == JCommandButton.CommandButtonKind.POPUP_ONLY) {
toUseDisabledIcon = !((JCommandButton) this.commandButton)
.getPopupModel().isEnabled();
} else {
toUseDisabledIcon = !this.commandButton.getActionModel()
.isEnabled();
}
return toUseDisabledIcon;
}
/**
* Paints command button vertical separator.
*
* @param graphics
* Graphics context.
* @param separatorArea
* Separator area.
*/
protected void paintButtonVerticalSeparator(Graphics graphics,
Rectangle separatorArea) {
this.buttonRendererPane.setBounds(0, 0, this.commandButton.getWidth(),
this.commandButton.getHeight());
Graphics2D g2d = (Graphics2D) graphics.create();
this.rendererSeparator.setOrientation(JSeparator.VERTICAL);
this.buttonRendererPane.paintComponent(g2d, this.rendererSeparator,
this.commandButton, separatorArea.x, 2, 2, this.commandButton
.getHeight() - 4, true);
g2d.dispose();
}
/**
* Paints command button horizontal separator.
*
* @param graphics
* Graphics context.
* @param separatorArea
* Separator area.
*/
protected void paintButtonHorizontalSeparator(Graphics graphics,
Rectangle separatorArea) {
this.buttonRendererPane.setBounds(0, 0, this.commandButton.getWidth(),
this.commandButton.getHeight());
Graphics2D g2d = (Graphics2D) graphics.create();
this.rendererSeparator.setOrientation(JSeparator.HORIZONTAL);
this.buttonRendererPane.paintComponent(g2d, this.rendererSeparator,
this.commandButton, 2, separatorArea.y, this.commandButton
.getWidth() - 4, 2, true);
g2d.dispose();
}
/**
* Paints command button background.
*
* @param graphics
* Graphics context.
* @param toFill
* Rectangle for the background.
*/
protected void paintButtonBackground(Graphics graphics, Rectangle toFill) {
ButtonModel actionModel = this.commandButton.getActionModel();
PopupButtonModel popupModel = (this.commandButton instanceof JCommandButton) ? ((JCommandButton) this.commandButton)
.getPopupModel()
: null;
// first time - paint the full background passing both models
this.paintButtonBackground(graphics, toFill, actionModel, popupModel);
Rectangle actionArea = this.getLayoutInfo().actionClickArea;
Rectangle popupArea = this.getLayoutInfo().popupClickArea;
if ((actionArea != null) && !actionArea.isEmpty()) {
// now overlay the action area with the background matching action
// model
Graphics2D graphicsAction = (Graphics2D) graphics.create();
// System.out.println(actionArea);
graphicsAction.clip(actionArea);
float actionAlpha = 0.4f;
if ((popupModel != null) && !popupModel.isEnabled())
actionAlpha = 1.0f;
graphicsAction.setComposite(AlphaComposite.SrcOver
.derive(actionAlpha));
// System.out.println(graphicsAction.getClipBounds());
this.paintButtonBackground(graphicsAction, toFill, actionModel);
graphicsAction.dispose();
}
if ((popupArea != null) && !popupArea.isEmpty()) {
// now overlay the popup area with the background matching popup
// model
Graphics2D graphicsPopup = (Graphics2D) graphics.create();
// System.out.println(popupArea);
graphicsPopup.clip(popupArea);
// System.out.println(graphicsPopup.getClipBounds());
float popupAlpha = 0.4f;
if (!actionModel.isEnabled())
popupAlpha = 1.0f;
graphicsPopup.setComposite(AlphaComposite.SrcOver
.derive(popupAlpha));
this.paintButtonBackground(graphicsPopup, toFill, popupModel);
graphicsPopup.dispose();
}
}
/**
* Paints the background of the command button.
*
* @param graphics
* Graphics context.
* @param toFill
* Rectangle to fill.
* @param modelToUse
* Button models to use for computing the background fill.
*/
protected void paintButtonBackground(Graphics graphics, Rectangle toFill,
ButtonModel... modelToUse) {
if (modelToUse.length == 0)
return;
if ((modelToUse.length == 1) && (modelToUse[0] == null))
return;
this.buttonRendererPane.setBounds(toFill.x, toFill.y, toFill.width,
toFill.height);
this.rendererButton.setRolloverEnabled(true);
boolean isEnabled = true;
boolean isRollover = false;
boolean isPressed = true;
boolean isArmed = true;
boolean isSelected = true;
for (ButtonModel model : modelToUse) {
if (model == null)
continue;
isEnabled = isEnabled && model.isEnabled();
isRollover = isRollover || model.isRollover();
isPressed = isPressed && model.isPressed();
isArmed = isArmed && model.isArmed();
isSelected = isSelected && model.isSelected();
if (model instanceof PopupButtonModel) {
isRollover = isRollover
|| ((PopupButtonModel) model).isPopupShowing();
}
}
this.rendererButton.getModel().setEnabled(isEnabled);
this.rendererButton.getModel().setRollover(isRollover);
this.rendererButton.getModel().setPressed(isPressed);
this.rendererButton.getModel().setArmed(isArmed);
this.rendererButton.getModel().setSelected(isSelected);
// System.out.println(this.commandButton.getText() + " - e:"
// + this.rendererButton.getModel().isEnabled() + ", s:"
// + this.rendererButton.getModel().isSelected() + ", r:"
// + this.rendererButton.getModel().isRollover() + ", p:"
// + this.rendererButton.getModel().isPressed() + ", a:"
// + this.rendererButton.getModel().isArmed());
Graphics2D g2d = (Graphics2D) graphics.create();
Color borderColor = FlamingoUtilities.getBorderColor();
if (Boolean.TRUE.equals(this.commandButton
.getClientProperty(EMULATE_SQUARE_BUTTON))) {
this.buttonRendererPane.paintComponent(g2d, this.rendererButton,
this.commandButton, toFill.x - toFill.width / 2, toFill.y
- toFill.height / 2, 2 * toFill.width,
2 * toFill.height, true);
g2d.setColor(borderColor);
g2d.drawRect(toFill.x, toFill.y, toFill.width - 1,
toFill.height - 1);
} else {
AbstractCommandButton.CommandButtonLocationOrderKind locationKind = this.commandButton
.getLocationOrderKind();
Insets outsets = (this.rendererButton instanceof JToggleButton) ? ButtonSizingUtils
.getInstance().getToggleOutsets()
: ButtonSizingUtils.getInstance().getOutsets();
if (locationKind != null) {
if (locationKind == AbstractCommandButton.CommandButtonLocationOrderKind.ONLY) {
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton, this.commandButton, toFill.x
- outsets.left, toFill.y - outsets.top,
toFill.width + outsets.left + outsets.right,
toFill.height + outsets.top + outsets.bottom, true);
} else {
// special case for parent component which is a vertical
// button strip
Component parent = this.commandButton.getParent();
if ((parent instanceof JCommandButtonStrip)
&& (((JCommandButtonStrip) parent).getOrientation() == StripOrientation.VERTICAL)) {
switch (locationKind) {
case FIRST:
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton, this.commandButton,
toFill.x - outsets.left, toFill.y
- outsets.top, toFill.width
+ outsets.left + outsets.right,
2 * toFill.height, true);
g2d.setColor(borderColor);
g2d.drawLine(toFill.x + 1, toFill.y + toFill.height
- 1, toFill.x + toFill.width - 2, toFill.y
+ toFill.height - 1);
break;
case LAST:
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton, this.commandButton,
toFill.x - outsets.left, toFill.y
- toFill.height, toFill.width
+ outsets.left + outsets.right, 2
* toFill.height + outsets.bottom,
true);
break;
case MIDDLE:
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton, this.commandButton,
toFill.x - outsets.left, toFill.y
- toFill.height, toFill.width
+ outsets.left + outsets.right,
3 * toFill.height, true);
g2d.setColor(borderColor);
g2d.drawLine(toFill.x + 1, toFill.y + toFill.height
- 1, toFill.x + toFill.width - 2, toFill.y
+ toFill.height - 1);
}
} else {
// horizontal
boolean ltr = this.commandButton
.getComponentOrientation().isLeftToRight();
if (locationKind == AbstractCommandButton.CommandButtonLocationOrderKind.MIDDLE) {
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton, this.commandButton,
toFill.x - toFill.width, toFill.y
- outsets.top, 3 * toFill.width,
toFill.height + outsets.top
+ outsets.bottom, true);
g2d.setColor(borderColor);
g2d.drawLine(toFill.x + toFill.width - 1,
toFill.y + 1, toFill.x + toFill.width - 1,
toFill.y + toFill.height - 2);
} else {
boolean curveOnLeft = (ltr && (locationKind == AbstractCommandButton.CommandButtonLocationOrderKind.FIRST))
|| (!ltr && (locationKind == AbstractCommandButton.CommandButtonLocationOrderKind.LAST));
if (curveOnLeft) {
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton,
this.commandButton, toFill.x
- outsets.left, toFill.y
- outsets.top,
2 * toFill.width, toFill.height
+ outsets.top + outsets.bottom,
true);
g2d.setColor(borderColor);
g2d.drawLine(toFill.x + toFill.width - 1,
toFill.y + 1, toFill.x + toFill.width
- 1, toFill.y + toFill.height
- 2);
} else {
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton,
this.commandButton, toFill.x
- toFill.width, toFill.y
- outsets.top, 2 * toFill.width
+ outsets.right, toFill.height
+ outsets.top + outsets.bottom,
true);
}
}
}
}
} else {
this.buttonRendererPane.paintComponent(g2d,
this.rendererButton, this.commandButton, toFill.x
- outsets.left, toFill.y - outsets.top,
toFill.width + outsets.left + outsets.right,
toFill.height + outsets.top + outsets.bottom, true);
}
}
g2d.dispose();
}
/**
* Updates the custom dimension.
*/
protected void updateCustomDimension() {
int dimension = this.commandButton.getCustomDimension();
if (dimension > 0) {
this.commandButton.getIcon().setDimension(
new Dimension(dimension, dimension));
this.commandButton
.setDisplayState(CommandButtonDisplayState.FIT_TO_ICON);
this.commandButton.invalidate();
this.commandButton.revalidate();
this.commandButton.doLayout();
this.commandButton.repaint();
}
}
/**
* Updates the popup action icon.
*/
protected void updatePopupActionIcon() {
JCommandButton button = (JCommandButton) this.commandButton;
if (button.getCommandButtonKind().hasPopup()) {
this.popupActionIcon = this.createPopupActionIcon();
} else {
this.popupActionIcon = null;
}
}
/**
* Paints the button icon.
*
* @param g
* Graphics context.
* @param iconRect
* Icon rectangle.
*/
protected void paintButtonIcon(Graphics g, Rectangle iconRect) {
Icon iconToPaint = this.getIconToPaint();
if ((iconRect == null) || (iconToPaint == null)
|| (iconRect.width == 0) || (iconRect.height == 0)) {
return;
}
iconToPaint.paintIcon(this.commandButton, g, iconRect.x, iconRect.y);
}
/*
* (non-Javadoc)
*
* @see
* javax.swing.plaf.ComponentUI#getPreferredSize(javax.swing.JComponent)
*/
@Override
public Dimension getPreferredSize(JComponent c) {
AbstractCommandButton button = (AbstractCommandButton) c;
return this.layoutManager.getPreferredSize(button);
}
@Override
public CommandButtonLayoutInfo getLayoutInfo() {
if (this.layoutInfo != null) {
return this.layoutInfo;
}
this.layoutInfo = this.layoutManager.getLayoutInfo(commandButton,
this.commandButton.getGraphics());
return this.layoutInfo;
}
/**
* Returns the layout gap for the visuals of the associated command button.
*
* @return The layout gap for the visuals of the associated command button.
*/
protected int getLayoutGap() {
Font font = this.commandButton.getFont();
if (font == null)
font = UIManager.getFont("Button.font");
return (font.getSize() - 4) / 4;
}
/**
* Returns indication whether the action-popup areas separator is painted.
*
* @return true
if the action-popup areas separator is painted.
*/
protected boolean isPaintingSeparators() {
PopupButtonModel popupModel = (this.commandButton instanceof JCommandButton) ? ((JCommandButton) this.commandButton)
.getPopupModel()
: null;
boolean isActionRollover = this.commandButton.getActionModel()
.isRollover();
boolean isPopupRollover = (popupModel != null)
&& popupModel.isRollover();
// Rectangle actionArea = this.getActionClickArea();
// Rectangle popupArea = this.getPopupClickArea();
// boolean hasNonEmptyAreas = (actionArea.width * actionArea.height
// * popupArea.width * popupArea.height > 0);
return // hasNonEmptyAreas &&
(isActionRollover || isPopupRollover);
}
/**
* Returns indication whether the button background is painted.
*
* @return true
if the button background is painted.
*/
protected boolean isPaintingBackground() {
PopupButtonModel popupModel = (this.commandButton instanceof JCommandButton) ? ((JCommandButton) this.commandButton)
.getPopupModel()
: null;
boolean isActionSelected = this.commandButton.getActionModel()
.isSelected();
boolean isPopupSelected = (popupModel != null)
&& popupModel.isSelected();
boolean isActionRollover = this.commandButton.getActionModel()
.isRollover();
boolean isPopupRollover = (popupModel != null)
&& popupModel.isRollover();
boolean isPopupShowing = (popupModel != null)
&& (popupModel.isPopupShowing());
boolean isActionArmed = this.commandButton.getActionModel().isArmed();
boolean isPopupArmed = (popupModel != null) && (popupModel.isArmed());
return (isActionSelected || isPopupSelected || isActionRollover
|| isPopupRollover || isPopupShowing || isActionArmed
|| isPopupArmed || !this.commandButton.isFlat());
}
/**
* Creates the popup action listener for this command button.
*
* @return Popup action listener for this command button.
*/
protected PopupActionListener createPopupActionListener() {
return new PopupActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
processPopupAction();
}
};
}
protected void processPopupAction() {
boolean wasPopupShowing = false;
if (this.commandButton instanceof JCommandButton) {
wasPopupShowing = ((JCommandButton) this.commandButton)
.getPopupModel().isPopupShowing();
}
// dismiss all the popups that are currently showing
// up until button.
PopupPanelManager.defaultManager().hidePopups(commandButton);
if (!(commandButton instanceof JCommandButton))
return;
if (wasPopupShowing)
return;
JCommandButton jcb = (JCommandButton) this.commandButton;
// check if the command button has an associated popup
// panel
PopupPanelCallback popupCallback = jcb.getPopupCallback();
final JPopupPanel popupPanel = (popupCallback != null) ? popupCallback
.getPopupPanel(jcb) : null;
if (popupPanel != null) {
popupPanel.applyComponentOrientation(jcb.getComponentOrientation());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if ((commandButton == null) || (popupPanel == null))
return;
if (!commandButton.isShowing())
return;
popupPanel.doLayout();
int x = 0;
int y = 0;
JPopupPanel.PopupPanelCustomizer customizer = popupPanel
.getCustomizer();
boolean ltr = commandButton.getComponentOrientation()
.isLeftToRight();
if (customizer == null) {
switch (((JCommandButton) commandButton)
.getPopupOrientationKind()) {
case DOWNWARD:
if (ltr) {
x = commandButton.getLocationOnScreen().x;
} else {
x = commandButton.getLocationOnScreen().x
+ commandButton.getWidth()
- popupPanel.getPreferredSize().width;
}
y = commandButton.getLocationOnScreen().y
+ commandButton.getSize().height;
break;
case SIDEWARD:
if (ltr) {
x = commandButton.getLocationOnScreen().x
+ commandButton.getWidth();
} else {
x = commandButton.getLocationOnScreen().x
- popupPanel.getPreferredSize().width;
}
y = commandButton.getLocationOnScreen().y
+ getLayoutInfo().popupClickArea.y;
break;
}
} else {
Rectangle placementRect = customizer.getScreenBounds();
// System.out.println(placementRect);
x = placementRect.x;
y = placementRect.y;
}
// make sure that the popup stays in bounds
Rectangle scrBounds = commandButton
.getGraphicsConfiguration().getBounds();
int pw = popupPanel.getPreferredSize().width;
if ((x + pw) > (scrBounds.x + scrBounds.width)) {
x = scrBounds.x + scrBounds.width - pw;
}
int ph = popupPanel.getPreferredSize().height;
if ((y + ph) > (scrBounds.y + scrBounds.height)) {
y = scrBounds.y + scrBounds.height - ph;
}
// get the popup and show it
if (customizer != null) {
Rectangle placementRect = customizer.getScreenBounds();
popupPanel.setPreferredSize(new Dimension(
placementRect.width, placementRect.height));
}
Popup popup = PopupFactory.getSharedInstance().getPopup(
commandButton, popupPanel, x, y);
// System.out.println("Showing the popup panel");
PopupPanelManager.defaultManager().addPopup(commandButton,
popup, popupPanel);
}
});
return;
}
}
protected void syncDisabledIcon() {
ResizableIcon currDisabledIcon = this.commandButton.getDisabledIcon();
ResizableIcon icon = this.commandButton.getIcon();
if ((currDisabledIcon == null)
|| (currDisabledIcon instanceof UIResource)) {
if (icon != null) {
this.commandButton.setDisabledIcon(new ResizableIconUIResource(
new FilteredResizableIcon(icon, new ColorConvertOp(
ColorSpace.getInstance(ColorSpace.CS_GRAY),
null))));
} else {
this.commandButton.setDisabledIcon(null);
}
} else {
// disabled icon coming from app code
if (icon != null) {
this.commandButton.getDisabledIcon()
.setDimension(
new Dimension(icon.getIconWidth(), icon
.getIconHeight()));
}
}
}
protected void syncIconDimension() {
ResizableIcon icon = this.commandButton.getIcon();
CommandButtonDisplayState commandButtonState = this.commandButton
.getDisplayState();
this.layoutManager = commandButtonState
.createLayoutManager(this.commandButton);
if (icon == null)
return;
int maxHeight = layoutManager.getPreferredIconSize();
if (maxHeight < 0) {
maxHeight = this.commandButton.getIcon().getIconHeight();
}
if (commandButtonState != CommandButtonDisplayState.FIT_TO_ICON) {
Dimension newDim = new Dimension(maxHeight, maxHeight);
icon.setDimension(newDim);
}
}
/*
* (non-Javadoc)
*
* @see
* org.jvnet.flamingo.common.ui.CommandButtonUI#getKeyTipAnchorCenterPoint()
*/
@Override
public Point getKeyTipAnchorCenterPoint() {
return this.layoutManager
.getKeyTipAnchorCenterPoint(this.commandButton);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy