All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.swingx.JXButton2 Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.jdesktop.swingx;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.swing.Action;
import javax.swing.ButtonModel;
import javax.swing.CellRendererPane;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.Painter;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.synth.SynthButtonUI;
import javax.swing.plaf.synth.SynthIcon;

import org.jdesktop.beans.JavaBean;
import org.jdesktop.swingx.graphics.FilterComposite;
import org.jdesktop.swingx.painter.AbstractPainter;
import org.jdesktop.swingx.painter.PainterPaint;
import org.jdesktop.swingx.util.GraphicsUtilities;
import org.jdesktop.swingx.util.PaintUtils;

/**
 * 

A {@link javax.swing.Painter} enabled subclass of {@link javax.swing.JButton}. * This class supports setting the foreground and background painters of the button separately.

* *

For example, if you wanted to blur just the text on the button, and let everything else be * handled by the UI delegate for your look and feel, then you could: *


 *  JXButton b = new JXButton("Execute");
 *  AbstractPainter fgPainter = (AbstractPainter)b.getForegroundPainter();
 *  StackBlurFilter filter = new StackBlurFilter();
 *  fgPainter.setFilters(filter);
 * 
* *

If either the foreground painter or the background painter is set, * then super.paintComponent() is not called. By setting both the foreground and background * painters to null, you get exactly the same painting behavior as JButton.

* * @author rbair * @author rah003 * @author Jan Stola * @author Karl George Schaefer */ @JavaBean @SuppressWarnings("serial") public class JXButton2 extends JButton implements BackgroundPaintable { private static final Logger LOG = Logger.getLogger(JXButton2.class.getName()); private class BackgroundButton extends JButton { /** * {@inheritDoc} */ @Override public boolean isDefaultButton() { return JXButton2.this.isDefaultButton(); } /** * {@inheritDoc} */ @Override public Icon getDisabledIcon() { return null; } /** * {@inheritDoc} */ @Override public Icon getDisabledSelectedIcon() { return null; } /** * {@inheritDoc} */ @Override public int getDisplayedMnemonicIndex() { return -1; } /** * {@inheritDoc} */ @Override public int getHorizontalAlignment() { return JXButton2.this.getHorizontalAlignment(); } /** * {@inheritDoc} */ @Override public int getHorizontalTextPosition() { return JXButton2.this.getHorizontalTextPosition(); } /** * {@inheritDoc} */ @Override public Icon getIcon() { return null; } /** * {@inheritDoc} */ @Override public int getIconTextGap() { return JXButton2.this.getIconTextGap(); } /** * {@inheritDoc} */ @Override public Insets getMargin() { return JXButton2.this.getMargin(); } /** * {@inheritDoc} */ @Override public int getMnemonic() { return -1; } /** * {@inheritDoc} */ @Override public ButtonModel getModel() { return JXButton2.this.getModel(); } /** * {@inheritDoc} */ @Override public Icon getPressedIcon() { return null; } /** * {@inheritDoc} */ @Override public Icon getRolloverIcon() { return null; } /** * {@inheritDoc} */ @Override public Icon getRolloverSelectedIcon() { return null; } /** * {@inheritDoc} */ @Override public Icon getSelectedIcon() { return null; } /** * {@inheritDoc} */ @Override public String getText() { return ""; } /** * {@inheritDoc} */ @Override public int getVerticalAlignment() { return JXButton2.this.getVerticalAlignment(); } /** * {@inheritDoc} */ @Override public int getVerticalTextPosition() { return JXButton2.this.getVerticalTextPosition(); } /** * {@inheritDoc} */ @Override public boolean isBorderPainted() { return JXButton2.this.isBorderPainted(); } /** * {@inheritDoc} */ @Override public boolean isContentAreaFilled() { return JXButton2.this.isContentAreaFilled(); } /** * {@inheritDoc} */ @Override public boolean isFocusPainted() { return false; } /** * {@inheritDoc} */ @Override public boolean isRolloverEnabled() { return JXButton2.this.isRolloverEnabled(); } /** * {@inheritDoc} */ @Override public boolean isSelected() { return JXButton2.this.isSelected(); } } private class ForegroundButton extends JButton { // private Icon iconBak; // TODO pro Laf dh map,Icon> // private Map,Icon> iconBak = new HashMap,Icon>(); private Map iconBak; // = new HashMap(); private String iconDescription; @Override public void updateUI() { ComponentUI cui = UIManager.getUI(this); LOG.info("ForegroundButton UI:"+cui + ", Icon:"+this.getIcon()); if(iconBak==null) { iconBak = new HashMap(); } /* ForegroundButton UI:javax.swing.plaf.metal.MetalButtonUI, Icon:sun.swing.ImageIconUIResource extends ImageIcon implements UIResource - beim Umschalten nach Nimbus bleibt es bei diesem Icon! Mögliche Lösung: - in ImageIcon kann man setDescription hinterlegen: ic.setDescription(UIManager.getLookAndFeel().getClass().getName() + ":" + key); - auch beim Umschalten nach Windows bleibt es bei diesem Icon! - dabei hat WindowsLookAndFeel eigene images ForegroundButton UI:javax.swing.plaf.synth.SynthButtonUI@2865bc56, Icon:javax.swing.plaf.nimbus.NimbusIcon ForegroundButton UI:javax.swing.plaf.metal.MetalButtonUI@18606a29, Icon:javax.swing.plaf.nimbus.NimbusIcon class NimbusIcon implements SynthIcon, UIResource - beim Zurückschalten nach Metal gibt es kein Icon */ if(!(cui instanceof SynthButtonUI) && getIcon() instanceof SynthIcon) { // not visible : class NimbusIcon if(iconDescription==null) { LOG.warning("ICON geht verloren!!!!!!!! iconDescription="+iconDescription); } else { int split = iconDescription.indexOf(':'); String lafClass = iconDescription.substring(0, split); String key = iconDescription.substring(split+1); if(iconBak.containsKey("javax.swing.plaf.nimbus.NimbusLookAndFeel")) { // backup existiert } else { iconBak.put("javax.swing.plaf.nimbus.NimbusLookAndFeel", getIcon()); } this.setIcon(UIManager.getIcon(key)); } } if(getIcon() instanceof ImageIcon ic) { // Icon:sun.swing.ImageIconUIResource extends ImageIcon if(iconBak.containsKey(UIManager.getLookAndFeel().getClass().getName()) && iconBak.get(UIManager.getLookAndFeel().getClass().getName())!=getIcon()) { this.setIcon(iconBak.get(UIManager.getLookAndFeel().getClass().getName())); // if(iconBak.get(UIManager.getLookAndFeel().getClass())!=null && getIcon()!=iconBak) { // this.setIcon(iconBak); } else { String lafAndName = ic.getDescription(); if(lafAndName!=null) { int split = lafAndName.indexOf(':'); String lafClass = lafAndName.substring(0, split); String key = lafAndName.substring(split+1); LOG.info(":"+lafClass + ", key/name:"+key + " >>>evtl neu:"+UIManager.getIcon(key)); if(!lafClass.equals(UIManager.getLookAndFeel().getClass().getName())) { // wenn sich laf geändert hat, dann this.iconDescription = lafAndName; //this.iconBak = getIcon(); iconBak.put(lafClass, getIcon()); this.setIcon(UIManager.getIcon(key)); } } } } } @Override public void setIcon(Icon icon) { LOG.info("neu Icon:"+icon); JXButton2.this.setIcon(icon); } @Override public Font getFont() { return JXButton2.this.getFont(); } /** * {@inheritDoc} */ @Override public Color getForeground() { if (fgPainter == null) { return JXButton2.this.getForeground(); } return PaintUtils.setAlpha(JXButton2.this.getForeground(), 0); } /** * {@inheritDoc} */ @Override public boolean isDefaultButton() { return JXButton2.this.isDefaultButton(); } /** * {@inheritDoc} */ @Override public Icon getDisabledIcon() { return JXButton2.this.getDisabledIcon(); } /** * {@inheritDoc} */ @Override public Icon getDisabledSelectedIcon() { return JXButton2.this.getDisabledSelectedIcon(); } /** * {@inheritDoc} */ @Override public int getDisplayedMnemonicIndex() { return JXButton2.this.getDisplayedMnemonicIndex(); } /** * {@inheritDoc} */ @Override public int getHorizontalAlignment() { return JXButton2.this.getHorizontalAlignment(); } /** * {@inheritDoc} */ @Override public int getHorizontalTextPosition() { return JXButton2.this.getHorizontalTextPosition(); } /** * {@inheritDoc} */ @Override public Icon getIcon() { return JXButton2.this.getIcon(); } /** * {@inheritDoc} */ @Override public int getIconTextGap() { return JXButton2.this.getIconTextGap(); } /** * {@inheritDoc} */ @Override public Insets getMargin() { return JXButton2.this.getMargin(); } /** * {@inheritDoc} */ @Override public int getMnemonic() { return JXButton2.this.getMnemonic(); } /** * {@inheritDoc} */ @Override public ButtonModel getModel() { return JXButton2.this.getModel(); } /** * {@inheritDoc} */ @Override public Icon getPressedIcon() { return JXButton2.this.getPressedIcon(); } /** * {@inheritDoc} */ @Override public Icon getRolloverIcon() { return JXButton2.this.getRolloverIcon(); } /** * {@inheritDoc} */ @Override public Icon getRolloverSelectedIcon() { return JXButton2.this.getRolloverSelectedIcon(); } /** * {@inheritDoc} */ @Override public Icon getSelectedIcon() { return JXButton2.this.getSelectedIcon(); } /** * {@inheritDoc} */ @Override public String getText() { return JXButton2.this.getText(); } /** * {@inheritDoc} */ @Override public int getVerticalAlignment() { return JXButton2.this.getVerticalAlignment(); } /** * {@inheritDoc} */ @Override public int getVerticalTextPosition() { return JXButton2.this.getVerticalTextPosition(); } /** * {@inheritDoc} */ @Override public boolean isBorderPainted() { return JXButton2.this.isBorderPainted(); } /** * {@inheritDoc} */ @Override public boolean isContentAreaFilled() { return false; } /** * {@inheritDoc} */ @Override public boolean hasFocus() { return JXButton2.this.hasFocus(); } /** * {@inheritDoc} */ @Override public boolean isFocusPainted() { return JXButton2.this.isFocusPainted(); } /** * {@inheritDoc} */ @Override public boolean isRolloverEnabled() { return JXButton2.this.isRolloverEnabled(); } /** * {@inheritDoc} */ @Override public boolean isSelected() { return JXButton2.this.isSelected(); } } private ForegroundButton fgStamp; private Painter fgPainter; private PainterPaint fgPaint; private BackgroundButton bgStamp; private Painter bgPainter; private boolean paintBorderInsets = true; private Rectangle viewRect = new Rectangle(); private Rectangle textRect = new Rectangle(); private Rectangle iconRect = new Rectangle(); /** * Creates a button with no set text or icon. */ public JXButton2() { init(); } /** * Creates a button with text. * * @param text * the text of the button */ public JXButton2(String text) { super(text); init(); } /** * Creates a button where properties are taken from the {@code Action} supplied. * * @param a * the {@code Action} used to specify the new button */ public JXButton2(Action a) { super(a); init(); } /** * Creates a button with an icon. * * @param icon * the Icon image to display on the button */ public JXButton2(Icon icon) { super(icon); init(); } /** * Creates a button with initial text and an icon. * * @param text * the text of the button * @param icon * the Icon image to display on the button */ public JXButton2(String text, Icon icon) { super(text, icon); init(); } protected void init(String text, Icon icon) { // INFORMATION: icon:sun.swing.ImageIconUIResource - extends ImageIcon implements UIResource // INFORMATION: icon:javax.swing.plaf.nimbus.NimbusIcon - not visible : implements SynthIcon, UIResource LOG.info("icon:"+icon + " Class:"+(icon==null?"no class":icon.getClass())); super.init(text, icon); } public void setIcon(Icon defaultIcon) { LOG.info("defaultIcon:"+defaultIcon); super.setIcon(defaultIcon); } private void init() { fgStamp = new ForegroundButton(); LOG.fine("fgStamp:"+fgStamp); } /** * {@inheritDoc} */ @Override public Painter getBackgroundPainter() { return bgPainter; } /** * {@inheritDoc} */ @Override public void setBackgroundPainter(Painter p) { Painter old = getBackgroundPainter(); this.bgPainter = p; firePropertyChange("backgroundPainter", old, getBackgroundPainter()); repaint(); } /** * @return the foreground painter for this button */ public Painter getForegroundPainter() { return fgPainter; } /** * set ForegroundPainter * @param p the Painter */ public void setForegroundPainter(Painter p) { Painter old = getForegroundPainter(); this.fgPainter = p; if (fgPainter == null) { fgPaint = null; } else { fgPaint = new PainterPaint(fgPainter, this); if (bgStamp == null) { bgStamp = new BackgroundButton(); } } firePropertyChange("foregroundPainter", old, getForegroundPainter()); repaint(); } /** * Returns true if the background painter should paint where the border is * or false if it should only paint inside the border. This property is * true by default. This property affects the width, height, * and initial transform passed to the background painter. */ @Override public boolean isPaintBorderInsets() { return paintBorderInsets; } /** * Sets the paintBorderInsets property. * Set to true if the background painter should paint where the border is * or false if it should only paint inside the border. This property is true by default. * This property affects the width, height, * and initial transform passed to the background painter. * * This is a bound property. */ @Override public void setPaintBorderInsets(boolean paintBorderInsets) { boolean old = this.isPaintBorderInsets(); this.paintBorderInsets = paintBorderInsets; firePropertyChange("paintBorderInsets", old, isPaintBorderInsets()); } /** * {@inheritDoc} */ @Override public Dimension getPreferredSize() { if (getComponentCount() == 1 && getComponent(0) instanceof CellRendererPane) { return BasicGraphicsUtils.getPreferredButtonSize(fgStamp, getIconTextGap()); } return super.getPreferredSize(); } /** * {@inheritDoc} */ @Override protected void paintComponent(Graphics g) { if (fgPainter == null && bgPainter == null) { super.paintComponent(g); } else { LOG.fine("fgPainter:"+fgPainter + " bgPainter:"+bgPainter); if (fgPainter == null) { Graphics2D g2d = (Graphics2D) g.create(); try{ paintWithoutForegroundPainter(g2d); } finally { g2d.dispose(); } } else if (fgPainter instanceof AbstractPainter && ((AbstractPainter) fgPainter).getFilters().length > 0) { paintWithForegroundPainterWithFilters(g); } else { // bgPainter <> null Graphics2D g2d = (Graphics2D) g.create(); try { paintWithForegroundPainterWithoutFilters(g2d); } finally { g2d.dispose(); } } } } private void paintWithoutForegroundPainter(Graphics2D g2d) { if (bgPainter == null) { SwingUtilities.paintComponent(g2d, bgStamp, this, 0, 0, getWidth(), getHeight()); } else { SwingXUtilities.paintBackground(this, g2d); } SwingUtilities.paintComponent(g2d, fgStamp, this, 0, 0, getWidth(), getHeight()); } private void paintWithForegroundPainterWithoutFilters(Graphics2D g2d) { paintWithoutForegroundPainter(g2d); if (getText() != null && !getText().isEmpty()) { Insets i = getInsets(); viewRect.x = i.left; viewRect.y = i.top; viewRect.width = getWidth() - (i.right + viewRect.x); viewRect.height = getHeight() - (i.bottom + viewRect.y); textRect.x = textRect.y = textRect.width = textRect.height = 0; iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0; // layout the text and icon String text = SwingUtilities.layoutCompoundLabel( this, g2d.getFontMetrics(), getText(), getIcon(), getVerticalAlignment(), getHorizontalAlignment(), getVerticalTextPosition(), getHorizontalTextPosition(), viewRect, iconRect, textRect, getText() == null ? 0 : getIconTextGap()); if (!isPaintBorderInsets()) { g2d.translate(i.left, i.top); } g2d.setPaint(fgPaint); BasicGraphicsUtils.drawStringUnderlineCharAt(g2d, text, getDisplayedMnemonicIndex(), textRect.x, textRect.y + g2d.getFontMetrics().getAscent()); } } private void paintWithForegroundPainterWithFilters(Graphics g) { BufferedImage im = GraphicsUtilities.createCompatibleTranslucentImage(getWidth(), getHeight()); Graphics2D g2d = im.createGraphics(); try { Graphics gfx = getComponentGraphics(g2d); assert gfx == g2d; paintWithForegroundPainterWithoutFilters(g2d); } finally { g2d.dispose(); } Graphics2D filtered = (Graphics2D) g.create(); try { for (BufferedImageOp filter : ((AbstractPainter) fgPainter).getFilters()) { filtered.setComposite(new FilterComposite(filtered.getComposite(), filter)); } filtered.drawImage(im, 0, 0, this); } finally { filtered.dispose(); } } /** * Notification from the UIManager that the LaF has changed. * Replaces the current UI object with the latest version from the UIManager. * * @see javax.swing.JComponent#updateUI */ @Override public void updateUI() { super.updateUI(); if (bgStamp != null) { bgStamp.updateUI(); } if (fgStamp != null) { fgStamp.updateUI(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy