0

正如标题所暗示的那样,我试图复制 JButton 上主要文本下方的文本,并将其向下移动一个像素。我正在尝试在其上获得类似阴影的效果,没有模糊,并且在文本正下方有一个像素。

我将如何做到这一点,使用 actionListener 而不是按钮设置 JPanel 会更容易吗?

代码 -

import java.awt.Color;
import java.awt.Component;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;

import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;

class ButtonUI extends JButton {

    private Color startColor = new Color(162, 110, 235);
    private Color endColor = new Color(110, 49, 237);
    private Color rollOverTopColor = new Color(171, 137, 219);
    private Color rollOverBottomColor = new Color(129, 89, 216);

    private Color pressedStartColor = new Color(73, 30, 113);
    private Color pressedMidColor = new Color(113, 57, 221);
    private Color pressedEndColor = new Color(93, 43, 198);

    private Color outerBorderColor = new Color(117, 14, 182);
    private Color innerBorderTopColor = new Color(178, 133, 237, 255);
    private Color innerBorderBottomColor = new Color(178, 133, 237, 150);

    /**
     * @param top
     *            , left, bottom, right
     */
    private Insets insetsForButtons = new Insets(0, 13, 4, 13);

    private int outerRoundRectSize = 4;
    private int innerRoundRectSize = 2;
    private GradientPaint GP;

    /**
     * 
     * @param text
     */
    public ButtonUI(String text) {
        super();
        setText(text);
        setAlignmentX(Component.CENTER_ALIGNMENT);
        setContentAreaFilled(false);
        setBorderPainted(false);
        setForeground(Color.WHITE);
        setFocusable(false);
        setMargin(insetsForButtons);

    }

    /**
     * 
     * @param startColor
     * @param endColor
     * @param rollOverColor
     * @param rollOverTopColor
     * @param rollOverBottomColor
     * @param pressedColor
     * @param pressedTopColor
     * @param pressedBottomColor
     */
    public ButtonUI(Color startColor, Color endColor, Color rollOverTopColor,
            Color rollOverBottomColor, Color pressedStartColor,
            Color pressedMidColor, Color pressedEndColor) {
        super();
        this.startColor = startColor;
        this.endColor = endColor;
        this.pressedStartColor = pressedStartColor;
        this.pressedMidColor = pressedMidColor;
        this.pressedEndColor = pressedEndColor;

        setForeground(Color.WHITE);
        setFocusable(false);
        setContentAreaFilled(false);
        setBorderPainted(false);
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        int h = getHeight();
        int w = getWidth();
        ButtonModel model = getModel();
        if (!model.isEnabled()) {
            setForeground(Color.BLACK);
            GP = new GradientPaint(0, 0, new Color(73, 30, 113), 0, h,
                    new Color(73, 30, 113), true);
        } else {
            setForeground(Color.WHITE);
            if (model.isRollover()) {
                GP = new GradientPaint(0, 0, rollOverTopColor, 0, h,
                        rollOverBottomColor, true);
            } else {
                GP = new GradientPaint(0, 0, startColor, 0, h, endColor, true);
            }
        }
        g2d.setPaint(GP);
        GradientPaint p1;
        GradientPaint p2;
        if (model.isPressed()) {
            GP = new GradientPaint(0, 0, pressedStartColor, 0, h,
                    pressedMidColor, true);
            g2d.setPaint(GP);
            p1 = new GradientPaint(0, 0, outerBorderColor, 0, h - 1,
                    outerBorderColor);

            // BE SURE TO EDIT TO MAKE LESS DRAMATIC
            p2 = new GradientPaint(0, 1, innerBorderTopColor, 0, h - 3,
                    innerBorderTopColor);
        } else {
            p1 = new GradientPaint(0, 0, outerBorderColor, 0, h - 1,
                    outerBorderColor);

            p2 = new GradientPaint(0, 1, innerBorderTopColor, 0, h - 3,
                    innerBorderBottomColor);

            GP = new GradientPaint(0, 0, startColor, 0, h, endColor, true);
        }
        RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1,
                h - 1, outerRoundRectSize, outerRoundRectSize);
        Shape clip = g2d.getClip();
        g2d.clip(r2d);
        g2d.fillRect(0, 0, w, h);
        g2d.setClip(clip);
        g2d.setPaint(p1);
        g2d.drawRoundRect(0, 0, w - 1, h - 1, outerRoundRectSize,
                outerRoundRectSize);
        g2d.setPaint(p2);
        g2d.drawRoundRect(1, 1, w - 3, h - 3, innerRoundRectSize,
                innerRoundRectSize);
        g2d.dispose();

        super.paintComponent(g);
    }
}

public class ButtonClass {

    public static void createGUI() {
        JFrame programFrame = new JFrame("Custom Button UI");
        ButtonUI testButton = new ButtonUI("Custom JButton UI!");

        programFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        programFrame.add(testButton);
        programFrame.pack();
        programFrame.setVisible(true);
        programFrame.setResizable(true);
        programFrame.setSize(250, 75);
        programFrame.setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createGUI();
            }
        });
    }
}

和往常一样,如果你对此投反对票,请解释我可以做得更好,这样就不会再发生了。

编辑:发布了我重写的 JButton 类,这是我用于所有按钮的,而不是为每个按钮制作这个。

4

1 回答 1

1

你需要解决两个问题:

  • 按钮的文本由其 UI 委托呈现;这里ButtonUI显示了一个习惯。

  • 可以以多种方式中的任何一种来渲染阴影。

附录:在您的更新中缺少sscce,我不确定什么没有按照您想要的方式工作。您可以尝试Icon将文本呈现为纯文本或阴影文本的实现,而不是自定义 UI 委托。使用此处setRolloverIcon()所示的方法根据需要更改图标。这可能有助于几何。LayoutTest

于 2013-05-20T09:22:47.167 回答