java - JButton 上的阴影/重复文本

标签 java swing text jbutton shadow

正如标题所示,我试图复制 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 类,这是我用于所有按钮的类,而不是为每个按钮都使用它。

最佳答案

您需要解决两个问题:

  • 按钮的文本由其 UI 委托(delegate)呈现;显示自定义 ButtonUI here .

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

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

关于java - JButton 上的阴影/重复文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16643323/

相关文章:

java - 调整 JPanel 的高度

java - 在 Mac OS X 中读取 Windows .CSV 文件

PHP 显示来自 MYSQL 的文本

html - 用于在 html 中标记文本的 Notepad++ 或 netbeans 插件

java - 我可以将 Google 的数据存储区用于桌面应用程序吗?

java - 是否可以在用 java 构建的 Android 应用程序中运行 AIR 播放器 (OSMF)?

Java:从文件加载图像,编辑并添加到 JPanel

java - 使用 Class.this.field = value 在构造函数中初始化最终字段会出错,而使用 this.field = value 则不会

java - 如何在 Struts 2 中提交多个模型?

java - 如何将 mouseClicked 事件添加到 Swing 表?