使用JButton在Java中创建自定义按钮

使用JButton在Java中创建自定义按钮,java,swing,user-interface,jbutton,actionlistener,Java,Swing,User Interface,Jbutton,Actionlistener,我试图创建一个具有自定义形状(六边形)的按钮,但在其他方面的行为与普通JButton类似(即,与ActionListener一起工作) 我创建了一个扩展AbstractButton的类,但当我单击它时,它似乎没有向ActionListener发送事件。如果我将类更改为扩展JButton,那么它可以很好地工作,但它会破坏按钮的显示方式。我假设有一种方法需要重写才能触发事件,但我不知道它是什么。尝试使用Jlabel并对任何形状使用图像 JLabel lbl = new JLabel("");

我试图创建一个具有自定义形状(六边形)的按钮,但在其他方面的行为与普通JButton类似(即,与ActionListener一起工作)


我创建了一个扩展AbstractButton的类,但当我单击它时,它似乎没有向ActionListener发送事件。如果我将类更改为扩展JButton,那么它可以很好地工作,但它会破坏按钮的显示方式。我假设有一种方法需要重写才能触发事件,但我不知道它是什么。

尝试使用Jlabel并对任何形状使用图像

    JLabel lbl = new JLabel("");
    lbl.setIcon(new ImageIcon("shape.png"));
    lbl.setBounds(548, 11, 66, 20);
    contentPane.add(lbl);

    lbl.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {
            System.exit(0);
        }
    });

您必须扩展
JButton
类而不是
AbstractButton
。试着做下面的事情,你就会明白

第一步是子类
JButton

然后,在子类中,首先重新定义
paintComponent(Graphics)
方法。如果你想要任何改变


然后,覆盖画框(图形),使其成为六边形。

如果要创建自定义按钮ui,则必须查看

  • 最深到
    basicxxui

  • 越过

注意没有
paintComponent()
。这是错误的,只需使用
paint()
方法

如果可能的话,下面只是一个简单的例子(对于金属JButton)。请注意,对于Metal LaF,我非常懒惰,没有关于覆盖paintText、paintIcon、paintFocus、paintBorder(对于所有函数,您必须检查BasicButtoni中可用的方法)的内容,也没有我放在ButtonModel中的内容,只是为了享受

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalButtonUI;

public class TextAreaInButton {

    private JFrame frame = new JFrame("sssssssss");
    private JButton tip1Null = new JButton(" test button ");

    public TextAreaInButton() {
        Border line, raisedbevel, loweredbevel, title, empty;
        line = BorderFactory.createLineBorder(Color.black);
        raisedbevel = BorderFactory.createRaisedBevelBorder();
        loweredbevel = BorderFactory.createLoweredBevelBorder();
        title = BorderFactory.createTitledBorder("");
        empty = BorderFactory.createEmptyBorder(1, 1, 1, 1);
        final Border compound;
        Color crl = (Color.blue);
        compound = BorderFactory.createCompoundBorder(empty, new OldRoundedBorderLine(crl));
        Color crl1 = (Color.red);
        final Border compound1;
        compound1 = BorderFactory.createCompoundBorder(empty, new OldRoundedBorderLine(crl1));
        Color crl2 = (Color.black);
        final Border compound2;
        compound2 = BorderFactory.createCompoundBorder(empty, new OldRoundedBorderLine(crl2));
        tip1Null.setFont(new Font("Serif", Font.BOLD, 14));
        tip1Null.setForeground(Color.darkGray);
        tip1Null.setPreferredSize(new Dimension(50, 30));
        tip1Null.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            }
        });
        tip1Null.setBorderPainted(true);
        tip1Null.setFocusPainted(false);
        tip1Null.setBorder(compound);
        tip1Null.setHorizontalTextPosition(SwingConstants.CENTER);
        tip1Null.setVerticalTextPosition(SwingConstants.BOTTOM);
        tip1Null.setUI(new ModifButtonUI());

        tip1Null.getModel().addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                ButtonModel model = (ButtonModel) e.getSource();
                if (model.isRollover()) {
                    tip1Null.setBorder(compound1);
                } else {
                    tip1Null.setBorder(compound);
                }
                if (model.isPressed()) {
                    tip1Null.setBorder(compound2);
                }
            }
        });

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(tip1Null, BorderLayout.CENTER);
        frame.setLocation(150, 150);
        frame.setPreferredSize(new Dimension(310, 75));
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                TextAreaInButton taib = new TextAreaInButton();
            }
        });
    }
}

class OldRoundedBorderLine extends AbstractBorder {

    private final static int MARGIN = 5;
    private static final long serialVersionUID = 1L;
    private Color color;

    OldRoundedBorderLine(Color clr) {
        color = clr;
    }

    public void setColor(Color clr) {
        color = clr;
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        ((Graphics2D) g).setRenderingHint(
            RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(color);
        g.drawRoundRect(x, y, width, height, MARGIN, MARGIN);
    }

    @Override
    public Insets getBorderInsets(Component c) {
        return new Insets(MARGIN, MARGIN, MARGIN, MARGIN);
    }

    @Override
    public Insets getBorderInsets(Component c, Insets insets) {
        insets.left = MARGIN;
        insets.top = MARGIN;
        insets.right = MARGIN;
        insets.bottom = MARGIN;
        return insets;
    }
}

class ModifButtonUI extends MetalButtonUI {

    private static final ModifButtonUI buttonUI = new ModifButtonUI();

    ModifButtonUI() {
    }

    public static ComponentUI createUI(JComponent c) {
        return new ModifButtonUI();
    }

    @Override
    public void paint(Graphics g, JComponent c) {
        final Color color1 = new Color(230, 255, 255, 0);
        final Color color2 = new Color(255, 230, 255, 64);
        final Color alphaColor = new Color(200, 200, 230, 64);
        final Color color3 = new Color(
            alphaColor.getRed(), alphaColor.getGreen(), alphaColor.getBlue(), 0);
        final Color color4 = new Color(
            alphaColor.getRed(), alphaColor.getGreen(), alphaColor.getBlue(), 64);
        super.paint(g, c);
        Graphics2D g2D = (Graphics2D) g;
        GradientPaint gradient1 = new GradientPaint(
            0.0F, (float) c.getHeight() / (float) 2, color1, 0.0F, 0.0F, color2);
        Rectangle rec1 = new Rectangle(0, 0, c.getWidth(), c.getHeight() / 2);
        g2D.setPaint(gradient1);
        g2D.fill(rec1);
        GradientPaint gradient2 = new GradientPaint(
            0.0F, (float) c.getHeight() / (float) 2, color3, 0.0F, c.getHeight(), color4);
        Rectangle rec2 = new Rectangle(0, c.getHeight() / 2, c.getWidth(), c.getHeight());
        g2D.setPaint(gradient2);
        g2D.fill(rec2);
    }

    @Override
    public void paintButtonPressed(Graphics g, AbstractButton b) {
        paintText(g, b, b.getBounds(), b.getText());
        g.setColor(Color.red.brighter());
        g.fillRect(0, 0, b.getSize().width, b.getSize().height);
    }

    public void paintBorder(Graphics g) {
    }

    @Override
    protected void paintFocus(Graphics g, AbstractButton b,
        Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
    }
}


我知道这个问题已经得到了回答,但是您可能想看看如何使用内置方法,以及如何使用图像在不同的状态下绘制按钮

下面是我用来生成自定义按钮的代码

BufferedImage startButton = ImageIO.read(getClass().getResource("/icons/standard/buttons/start_backup.png"));
BufferedImage startButtonHover = ImageIO.read(getClass().getResource("/icons/standard/buttons/start_backup_hover.png"));
BufferedImage startButtonActive = ImageIO.read(getClass().getResource("/icons/standard/buttons/start_backup_active.png"));

JButton startBackupButton = new JButton(new ImageIcon(startButton));
startBackupButton.setRolloverIcon(new ImageIcon(startButtonHover));
startBackupButton.setPressedIcon(new ImageIcon(startButtonActive));
startBackupButton.setBorder(BorderFactory.createEmptyBorder());
startBackupButton.setContentAreaFilled(false);
startBackupButton.setFocusable(false);

然后,您可以像平常一样向其添加操作侦听器。

我已经重新定义了paintComponent和paintBorder,但如果您单击其中一个按钮,它仍然会绘制方形边框。您是在自定义逻辑之后还是之前调用super.paintXXX()方法?我根本不调用super.paint。只是将其打印出来。。。完全按照你说的做了,但也在构造函数中添加了
this.setContentAreaFilled(false)
Errrgh,有人能给我解释一下,有什么错误的字符将代码拆分到这个生物,只需从IDE复制+粘贴,只需缩进四个空格,例如NetBeans'
控制向右移位
。在SO编辑器中,选择并单击
{}
图标+1个例子,顺便说一句。我从另一个论坛尝试了AllKnowsWoodoo,可能是Stars导入“*”。。。我的手和我的头之间有点不对劲,无论如何,我要感谢格式化的代码来恢复上次编辑中丢失的行;如果不正确,请还原。在MacOSX上,我使用了
-Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel
来查看全部效果。谢谢这个非常好的例子+1我随意添加了您的
按钮的图像。请参见此处: