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 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); }