2011-04-22 84 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

相關問題