2011-04-22 66 views
36

Estoy tratando de crear un botón que tenga una forma personalizada (hexágono), pero de lo contrario actúa como un JButton normal (es decir, funciona con un ActionListener).Crear un botón personalizado en Java con JButton

He creado una clase que amplía AbstractButton, pero no parece estar enviando eventos al ActionListener cuando hago clic en él. Si cambio la clase para extender JButton, funciona perfectamente, pero daña la forma en que se muestra el botón. Asumo que hay un método que debo anular para activar los eventos, pero no puedo entender cuál es.

+0

ver aquí: http://stackoverflow.com/a/11742552/478765 – ed22

Respuesta

14

Usted tendrá que extender JButton clase no AbstractButton. Pruebe las siguientes cosas y obtendrá una idea.

El primer movimiento es a la subclase JButton.

Luego, en su subclase, comience redefiniendo el método paintComponent(Graphics). Si quieres algún cambio

Luego, anule paintBorder(Graphics) para darle una forma de hexágono.

+0

Ya había redefinido paintComponent y paintBorder, pero todavía pinta un borde cuadrado si hace clic en uno de los botones. – rybl

+0

¿Está llamando al método super.paintXXX() después de su lógica personalizada o antes? – u449355

+0

No estoy llamando a super.paint en absoluto. – rybl

6

prueba un Jlabel y usa una imagen para cualquier forma !!

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

Necesito poder pasarlo a ActionListener – rybl

50

Si desea crear un CustomButtonUI entonces usted tiene que mirar

Nota no hay paintComponent(). Está mal, solo use el método paint(),

A continuación se muestra un ejemplo simple si eso es posible (para Metal JButton). Nota solo para Metal LaF, soy tan vago y no hay nada sobre reemplazar paintText, paintIcon, paintFocus, paintBorder (para todas las funcionalidades tienes que verificar los métodos disponibles desde BasicButtonUI), y algo que puse al ButtonModel, solo para mi disfrute

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, ¿alguien me puede explicar qué código (s) de código incorrecto (s) ha dividido a esta criatura, solo copie y pegue desde IDE – mKorbel

+0

Solo sangría cuatro espacios, p. NetBeans 'control-shift-right'. En el editor de SO, seleccione y haga clic en el ícono '{}'. +1 ejemplo, por cierto. –

+0

Intenté saber todo el woodoo de otros foros, quizás Stars Imports "*" ... algo malo entre las manos y mi cabeza, de todos modos, gracias – mKorbel

10

Sé que esta pregunta ha sido contestada, pero es posible que desee buscar en el uso de los métodos incorporados, y el uso de imágenes para llamar su botón en diferentes estados.

Aquí hay un poco de código que utilicé para generar un botón personalizado.

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

Puede agregar un detector de acciones como normal.

+0

¿Alguna explicación para el downvote? Creo que es un ejemplo válido. – Redandwhite

+0

No lo sé, otra posible ... – mKorbel

Cuestiones relacionadas