2011-04-22 137 views
36

我想创建一个具有自定义形状(六边形)的按钮,但是除此之外,就像普通的JButton一样(即与ActionListener一起工作)。使用JButton在Java中创建一个自定义按钮

我创建了一个扩展了AbstractButton的类,但是当我点击它时,它似乎没有将事件发送到ActionListener。如果我改变这个类来扩展JButton,它可以很好地工作,但它会影响按钮的显示方式。我假设有一种方法,我需要重写它来引发事件,但我无法弄清楚它是什么。

+0

看到这里:http://stackoverflow.com/a/11742552/478765 – ed22 2016-05-25 13:26:15

回答

14

你将不得不延长JButton类不AbstractButton。尝试以下事情,你会明白。

第一步是子类JButton

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

然后,覆盖paintBorder(Graphics)给它一个六边形的形状。

+0

我已经重新定义了paintComponent和paintBorder,但它仍然绘制一个方形边框,如果你点击一个的按钮。 – rybl 2011-04-22 01:04:09

+0

您是在自定义逻辑之后还是之前调用super.paintXXX()方法? – u449355 2011-04-22 01:08:06

+0

我根本不打电话给super.paint。 – rybl 2011-04-22 01:11:47

6

尝试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); 
     } 
    }); 
+0

我需要能够通过它一个ActionListener – rybl 2011-04-22 01:05:03

50

如果你想创建一个CustomButtonUI,那么你必须看看

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

下面只是一个简单的例子,如果这是可能的(金属JButton)。请注意,对于Metal LaF,我太懒惰了,没有关于重写paintText,paintIcon,paintFocus,paintBorder(对于所有功能,您必须从BasicButtonUI检查可用方法)以及我放到ButtonModel的东西,仅用于我的享受。

test button image

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) { 
    } 
} 
+0

Errrrgh,我可以有人解释我,错误的char(s)拆分代码到这个生物,只需从IDE复制+粘贴 – mKorbel 2011-04-22 12:04:02

+0

只需缩进四个空格,例如NetBeans的'control-shift-right'。在SO编辑器中,选择并单击“{}”图标。 +1例子,顺便说一句。 – 2011-04-22 17:14:13

+0

我试过所有知道从另一个论坛woodoo,也许星级进口“*”...手和我的头之间的东西错了,无论如何感谢 – mKorbel 2011-04-22 18:30:28

10

我知道这个问题已经回答了,但你可能想看看使用内置的方法,并利用图像绘制在不同状态下的按钮。

这是我用来生成自定义按钮的一些代码。

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

然后,您可以像往常一样添加一个动作侦听器。

+0

downvote的任何解释?我相信这是一个有效的例子。 – Redandwhite 2012-08-27 13:06:04

+0

我不知道,另一个可能... – mKorbel 2012-08-29 09:12:37

相关问题