Pregunta

¿Hay alguna manera de crear una JButton ¿Con tu propio gráfico de botón y no solo con una imagen dentro del botón?

Si no, ¿hay otra manera de crear una personalización? JButton en java?

¿Fue útil?

Solución

Cuando estaba aprendiendo Java por primera vez, teníamos que crear Yahtzee y pensé que sería genial crear componentes y contenedores Swing personalizados en lugar de simplemente dibujar todo en uno. JPanel.El beneficio de extender Swing componentes, por supuesto, es tener la capacidad de agregar soporte para atajos de teclado y otras características de accesibilidad que no puedes hacer simplemente teniendo un paint() método imprime una imagen bonita.Puede que no se haga de la mejor manera, pero puede ser un buen punto de partida para usted.

Edición 6/8: si no se desprende de las imágenes, cada troquel es un botón en el que puedes hacer clic.Esto lo moverá a la DiceContainer abajo.Al observar el código fuente, puede ver que cada botón Die se dibuja dinámicamente, según su valor.

alt text
alt text
alt text

Aquí están los pasos básicos:

  1. Crear una clase que se extienda JComponent
  2. Llamar al constructor padre super() en tus constructores
  3. Asegúrate de tener implementos de clase. MouseListener
  4. Pon esto en el constructor:

    enableInputMethods(true);   
    addMouseListener(this);
    
  5. Anule estos métodos:

    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
    
  6. Anule este método:

    public void paintComponent(Graphics g)
    

La cantidad de espacio con la que tienes que trabajar al dibujar tu botón está definida por getPreferredSize(), asumiendo getMinimumSize() y getMaximumSize() devolver el mismo valor.No he experimentado mucho con esto pero, dependiendo del diseño que uses para tu GUI, tu botón podría verse completamente diferente.

Y finalmente, el código fuente.Por si me perdí algo.

Otros consejos

Sí, esto es posible.Una de las principales ventajas de usar Swing es la facilidad con la que se pueden crear y manipular controles abstractos.

Aquí hay una manera rápida y sencilla de extender la clase JButton existente para dibujar un círculo a la derecha del texto.

package test;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MyButton extends JButton {

    private static final long serialVersionUID = 1L;

    private Color circleColor = Color.BLACK;

    public MyButton(String label) {
        super(label);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Dimension originalSize = super.getPreferredSize();
        int gap = (int) (originalSize.height * 0.2);
        int x = originalSize.width + gap;
        int y = gap;
        int diameter = originalSize.height - (gap * 2);

        g.setColor(circleColor);
        g.fillOval(x, y, diameter, diameter);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        size.width += size.height;
        return size;
    }

    /*Test the button*/
    public static void main(String[] args) {
        MyButton button = new MyButton("Hello, World!");

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);

        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new FlowLayout());
        contentPane.add(button);

        frame.setVisible(true);
    }

}

Tenga en cuenta que al anular componente de pintura que el contenido del botón se puede cambiar, pero que el borde está pintado por el pintarborde método.El obtener tamaño preferido El método también debe gestionarse para admitir dinámicamente cambios en el contenido.Se debe tener cuidado al medir las métricas de fuentes y las dimensiones de la imagen.

Para crear un control en el que pueda confiar, el código anterior no es el enfoque correcto.Las dimensiones y los colores son dinámicos en Swing y dependen de la apariencia que se utilice.Incluso el valor predeterminado Metal La apariencia ha cambiado en las versiones de JRE.Sería mejor implementar ResumenBotón y cumplir con las pautas establecidas por la API Swing.Un buen punto de partida es observar el javax.swing.LookAndFeel y javax.swing.UIManager clases.

http://docs.oracle.com/javase/8/docs/api/javax/swing/LookAndFeel.html

http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html

Comprender la anatomía de LookAndFeel es útil para escribir controles:Crear una apariencia personalizada

Siempre puedes probar la apariencia y sensación del sintetizador.Proporciona un archivo xml que actúa como una especie de hoja de estilo, junto con las imágenes que desee utilizar.El código podría verse así:

try {
    SynthLookAndFeel synth = new SynthLookAndFeel();
    Class aClass = MainFrame.class;
    InputStream stream = aClass.getResourceAsStream("\\default.xml");

    if (stream == null) {
        System.err.println("Missing configuration file");
        System.exit(-1);                
    }

    synth.load(stream, aClass);

    UIManager.setLookAndFeel(synth);
} catch (ParseException pe) {
    System.err.println("Bad configuration file");
    pe.printStackTrace();
    System.exit(-2);
} catch (UnsupportedLookAndFeelException ulfe) {
    System.err.println("Old JRE in use. Get a new one");
    System.exit(-3);
}

A partir de ahí, continúa y agrega tu JButton como lo harías normalmente.El único cambio es que utiliza el método setName(string) para identificar a qué debe asignarse el botón en el archivo xml.

El archivo xml podría verse así:

<synth>
    <style id="button">
        <font name="DIALOG" size="12" style="BOLD"/>
        <state value="MOUSE_OVER">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
        <state value="ENABLED">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
    </style>
    <bind style="button" type="name" key="dirt"/>
</synth>

El elemento de enlace especifica a qué asignar (en este ejemplo, aplicará ese estilo a cualquier botón cuya propiedad de nombre se haya establecido en "suciedad").

Y un par de enlaces útiles:

http://javadesktop.org/articles/synth/

http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html

Probablemente estoy yendo un millón de millas en la dirección equivocada (pero solo soy joven :P).pero ¿no podría agregar el gráfico a un panel y luego un escucha del mouse al objeto gráfico para que cuando el usuario esté en el gráfico se realice su acción?

No he desarrollado SWING desde mis primeras clases de informática, pero si no estuviera integrado, podrías heredar javax.swing.AbstractButton y crea el tuyo propio.Debería ser bastante sencillo conectar algo con su marco existente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top