public void paint(Graphics g, JComponent c) { AbstractButton b = (AbstractButton) c; ButtonModel model = b.getModel(); String text = layout(b, SwingUtilities2.getFontMetrics(b, g), b.getWidth(), b.getHeight()); clearTextShiftOffset(); // perform UI specific press action, e.g. Windows L&F shifts text if (model.isArmed() && model.isPressed()) { paintButtonPressed(g, b); } // Paint the Icon if (b.getIcon() != null) { paintIcon(g, c, iconRect); } if (text != null && !text.equals("")) { View v = (View) c.getClientProperty(BasicHTML.propertyKey); if (v != null) { v.paint(g, textRect); } else { paintText(g, b, textRect, text); } } if (b.isFocusPainted() && b.hasFocus()) { // paint UI specific focus paintFocus(g, b, viewRect, textRect, iconRect); } }
/** * This checks to see if updateLayout() needs to be called. Generally this returns true if the * width, height, or segment position has changed. */ protected boolean isLayoutValid(AbstractButton button) { int horizontalPosition = getHorizontalPosition(button); int verticalPosition = getVerticalPosition(button); int width = button.getWidth(); int height = button.getHeight(); String key = width + " " + height + " " + horizontalPosition + " " + verticalPosition; String oldKey = (String) button.getClientProperty("FilledButtonUI.validationKey"); if (oldKey == null) return false; if (oldKey.equals(key)) return true; return false; }
public void layoutComponents() { setLayout(new BorderLayout()); add(main, BorderLayout.CENTER); if (popperIsVisible) { if (getPopperButtonLocation() == RIGHT) { popper.setPreferredSize(new Dimension(14, main.getHeight())); add(popper, BorderLayout.EAST); } else if (getPopperButtonLocation() == BOTTOM) { popper.setPreferredSize(new Dimension(main.getWidth(), 14)); add(popper, BorderLayout.SOUTH); setPopperArrowDirection(DOWN); setPopupLocation(popper.getX(), popper.getY() + popper.getHeight() + 5); } } Utilities.updateView(this); }
protected void updateLayout(AbstractButton button, ButtonInfo buttonInfo) { Shape customShape = (Shape) button.getClientProperty(SHAPE); int width = button.getWidth(); int height = button.getHeight(); int horizontalPosition = getHorizontalPosition(button); int verticalPosition = getVerticalPosition(button); String key = width + " " + height + " " + horizontalPosition + " " + verticalPosition; button.putClientProperty("FilledButtonUI.validationKey", key); int dx = 0; int dy = 0; if (getFocusPainting(button) == PaintFocus.OUTSIDE || getFocusPainting(button) == PaintFocus.BOTH) { if (horizontalPosition == POS_LEFT || horizontalPosition == POS_ONLY) { dx += focusSize; width -= focusSize; } if (horizontalPosition == POS_RIGHT || horizontalPosition == POS_ONLY) { width -= focusSize; } if (verticalPosition == POS_TOP || verticalPosition == POS_ONLY) { dy += focusSize; height -= focusSize; } if (verticalPosition == POS_BOTTOM || verticalPosition == POS_ONLY) { height -= focusSize; } } else { if ((verticalPosition == POS_BOTTOM || verticalPosition == POS_ONLY) && fill.getShadowHighlight(button) != null) { height--; } } ButtonInfo info = getButtonInfo(button); boolean showSeparators = isShowingSeparators(button); shape.getShape( info.fill, info.stroke, width, height, horizontalPosition, verticalPosition, showSeparators, customShape); AffineTransform translation = AffineTransform.getTranslateInstance(dx, dy); info.fill.transform(translation); info.stroke.transform(translation); Font font = button.getFont(); if (font == null) font = new Font("Default", 0, 12); FontMetrics fm = button.getFontMetrics(font); info.viewRect.x = info.viewRect.y = info.textRect.x = info.textRect.y = info.textRect.width = info.textRect.height = 0; info.iconRect.x = info.iconRect.y = info.iconRect.width = info.iconRect.height = 0; info.viewRect.width = Short.MAX_VALUE; info.viewRect.height = Short.MAX_VALUE; SwingUtilities.layoutCompoundLabel( fm, button.getText(), button.getIcon(), button.getVerticalAlignment(), button.getHorizontalAlignment(), button.getVerticalTextPosition(), button.getHorizontalTextPosition(), info.viewRect, info.iconRect, info.textRect, button.getIconTextGap()); Insets textInsets = getTextPadding(); Insets iconInsets = getIconPadding(); Rectangle tempTextRect = new Rectangle(info.textRect); Rectangle tempIconRect = new Rectangle(info.iconRect); if (info.textRect.width > 0) { tempTextRect.y -= textInsets.top; tempTextRect.x -= textInsets.left; tempTextRect.width += textInsets.left + textInsets.right; tempTextRect.height += textInsets.top + textInsets.bottom; } if (info.iconRect.width > 0) { tempIconRect.y -= iconInsets.top; tempIconRect.x -= iconInsets.left; tempIconRect.width += iconInsets.left + iconInsets.right; tempIconRect.height += iconInsets.top + iconInsets.bottom; } Rectangle sum = getSum(new Rectangle[] {tempIconRect, tempTextRect}); Insets padding = getContentInsets(button); float centerX, centerY; if (button.getHorizontalAlignment() == SwingConstants.LEFT || button.getHorizontalAlignment() == SwingConstants.LEADING) { centerX = padding.left + sum.width / 2; } else if (button.getHorizontalAlignment() == SwingConstants.RIGHT || button.getHorizontalAlignment() == SwingConstants.TRAILING) { centerX = button.getWidth() - padding.right - sum.width / 2; } else { centerX = ((button.getWidth() - padding.left - padding.right)) / 2f; } // TODO: also take into account vertical alignment: centerY = ((button.getHeight() - padding.top - padding.bottom)) / 2f; float shiftX = centerX - (sum.width) / 2f - sum.x + padding.left; float shiftY = centerY - (sum.height) / 2f - sum.y + padding.top; if (customShape == null) { if (button.getVerticalAlignment() == SwingConstants.CENTER && button.getVerticalTextPosition() == SwingConstants.CENTER && info.textRect.width > 0) { int unusedAscent = getUnusedAscent(fm, font); int ascent = fm.getAscent() - unusedAscent; shiftY = (int) (-sum.y + centerY - ascent / 2 - unusedAscent + padding.top - textInsets.top); } } info.iconRect.setFrame( info.iconRect.x + shiftX, info.iconRect.y + shiftY, info.iconRect.width, info.iconRect.height); info.textRect.setRect( (int) (info.textRect.x + shiftX + .5f), (int) (info.textRect.y + shiftY + .5f), info.textRect.width, info.textRect.height); info.updateFillBounds(); }
/** * This calls the other relevant <code>paint...()</code> methods in this object. The layering of * the focus varies based on whether it should be painted outside or inside the filled shape, but * otherwise the layers are: * * <ul> * <li>Filling the bounds with <code>button.getBackground()</code> (if <code>button.isOpaque() * </code> is true). * <li>If <code>getShadowHighlight()</code> is non-null, painting the stroke/border 1 pixel * below its usual location. * <li><code>paintBackground(g)</code> * <li><code>paintEffects(g,false)</code> * <li><code>paintIcon(g)</code> * <li><code>paintText(g)</code> * <LI><code>paintForeground(g)</code> * <LI><code>paintEffects(g,true)</code> * </ul> */ @Override public void paint(Graphics g0, JComponent c) { AbstractButton button = (AbstractButton) c; if (isLayoutValid(button) == false) updateLayout(button, getButtonInfo(button)); if (button.isOpaque()) { g0.setColor(button.getBackground()); g0.fillRect(0, 0, button.getWidth(), button.getHeight()); } Graphics2D g = new OptimizedGraphics2D((Graphics2D) g0); g.setComposite(getComposite(button)); ButtonInfo info = getButtonInfo(button); Color highlight = fill.getShadowHighlight(button); if (highlight != null && isStrokePainted(button)) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.translate(0, 1); g.setColor(highlight); g.draw(info.fill); g.translate(0, -1); } PaintFocus focus = getFocusPainting(button); boolean hasFocus = hasFocus(button); if (Boolean.FALSE.equals(hasFocus) || button.isFocusPainted() == false) focus = PaintFocus.NONE; // this shouldn't be an issue, but just in case: if (isEnabled(button) == false) focus = PaintFocus.NONE; if (focus == PaintFocus.OUTSIDE) { if (isFillOpaque()) { // the opaque fill will overwrite the inner part of // this stroke... PlafPaintUtils.paintFocus(g, info.stroke, focusSize); } else { // this still has some rendering quirks in // Quartz (remove the clipping to study closely) // ... but other than the top horizontal & vertical // line it's OK. And even those are ... partly there. Graphics2D focusG = (Graphics2D) g.create(); GeneralPath outsideClip = new GeneralPath(Path2D.WIND_EVEN_ODD); outsideClip.append(new Rectangle(0, 0, button.getWidth(), button.getHeight()), false); outsideClip.append(info.fill, false); focusG.clip(outsideClip); PlafPaintUtils.paintFocus(focusG, info.stroke, focusSize); focusG.dispose(); } } g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); paintBackground(g, info); paintEffects(g, info, true); g.setStroke(new BasicStroke(1)); if (focus == PaintFocus.INSIDE) { Graphics2D focusG = (Graphics2D) g.create(); focusG.clip(info.fill); PlafPaintUtils.paintFocus(focusG, info.stroke, focusSize); focusG.dispose(); paintStroke(g, info); } else if (focus == PaintFocus.BOTH) { paintStroke(g, info); PlafPaintUtils.paintFocus(g, info.stroke, focusSize); } else { paintStroke(g, info); } g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); paintIcon(g, info); paintText(g, info); g.setComposite(isEnabled(button) ? AlphaComposite.SrcOver : SRC_OVER_TRANSLUCENT); paintForeground(g, info); paintEffects(g, info, false); }