swing - Erstellen eines benutzerdefinierten JButton in Java

Translate

Gibt es eine Möglichkeit, eine zu erstellenJButtonmit Ihrer eigenen Schaltflächengrafik und nicht nur mit einem Bild innerhalb der Schaltfläche?

Wenn nicht, gibt es eine andere Möglichkeit, eine benutzerdefinierte zu erstellenJButtonin Java?

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Als ich Java zum ersten Mal lernte, mussten wir Yahtzee erstellen und ich dachte, es wäre cool, benutzerdefinierte Swing-Komponenten und -Container zu erstellen, anstatt nur alles auf einen zu zeichnenJPanel. Der Vorteil der ErweiterungSwingKomponenten müssen natürlich die Möglichkeit haben, Tastaturkürzel und andere Eingabehilfen zu unterstützen, die Sie nicht einfach mit einem ausführen könnenpaint()Methode drucken Sie ein hübsches Bild. Es kann jedoch nicht der beste Weg sein, aber es kann ein guter Ausgangspunkt für Sie sein.

Bearbeiten 8/6 - Wenn dies aus den Bildern nicht ersichtlich ist, ist jeder Würfel eine Schaltfläche, auf die Sie klicken können. Dadurch wird es in die verschobenDiceContainerunten. Wenn Sie sich den Quellcode ansehen, sehen Sie, dass jede Die-Schaltfläche basierend auf ihrem Wert dynamisch gezeichnet wird.

alt text
alt text
alt text

Hier sind die grundlegenden Schritte:

  1. Erstellen Sie eine Klasse, die erweitert wirdJComponent
  2. Rufen Sie den übergeordneten Konstruktor aufsuper()in Ihren Konstruktoren
  3. Stellen Sie sicher, dass Sie Geräte implementierenMouseListener
  4. Geben Sie dies in den Konstruktor ein:

    enableInputMethods(true);   
    addMouseListener(this);
    
  5. Überschreiben Sie diese Methoden:

    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
    
  6. Überschreiben Sie diese Methode:

    public void paintComponent(Graphics g)
    

Der Platz, mit dem Sie beim Zeichnen Ihrer Schaltfläche arbeiten müssen, wird durch definiertgetPreferredSize()unter der AnnahmegetMinimumSize()undgetMaximumSize()Geben Sie den gleichen Wert zurück. Ich habe nicht zu viel damit experimentiert, aber je nach dem Layout, das Sie für Ihre GUI verwenden, kann Ihre Schaltfläche völlig anders aussehen.

Und schließlich dieQuellcode. Für den Fall, dass ich etwas verpasst habe.

Quelle
Translate

Ja, das ist möglich. Einer der Hauptprofis für die Verwendung von Swing ist die Leichtigkeit, mit der abstrakte Steuerelemente erstellt und bearbeitet werden können.

Hier ist eine schnelle und schmutzige Möglichkeit, die vorhandene JButton-Klasse zu erweitern, um einen Kreis rechts vom Text zu zeichnen.

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

    /^est 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);
    }

}

Beachten Sie dies durch ÜberschreibenpaintComponentdass der Inhalt der Schaltfläche geändert werden kann, der Rand jedoch von der gezeichnet wirdpaintBorderMethode. DasgetPreferredSizeDie Methode muss auch verwaltet werden, um Änderungen am Inhalt dynamisch zu unterstützen. Bei der Messung von Schriftmetriken und Bildabmessungen ist Vorsicht geboten.

Für die Erstellung eines Steuerelements, auf das Sie sich verlassen können, ist der obige Code nicht der richtige Ansatz. Abmessungen und Farben sind in Swing dynamisch und hängen vom verwendeten Erscheinungsbild ab. Sogar die StandardeinstellungMetallDas Aussehen hat sich in den JRE-Versionen geändert. Es wäre besser zu implementierenAbstractButtonund entsprechen den Richtlinien der Swing-API. Ein guter Ausgangspunkt ist der Blick auf diejavax.swing.LookAndFeelundjavax.swing.UIManagerKlassen.

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

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

Das Verständnis der Anatomie von LookAndFeel ist nützlich, um Steuerelemente zu schreiben:Erstellen eines benutzerdefinierten Erscheinungsbilds

Quelle
Translate

Sie können immer das Synth Look & Feel ausprobieren. Sie stellen eine XML-Datei bereit, die als eine Art Stylesheet fungiert, sowie alle Bilder, die Sie verwenden möchten. Der Code könnte folgendermaßen aussehen:

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

Von dort aus fügen Sie Ihren JButton wie gewohnt hinzu. Die einzige Änderung besteht darin, dass Sie die Methode setName (Zeichenfolge) verwenden, um zu identifizieren, wem die Schaltfläche in der XML-Datei zugeordnet werden soll.

Die XML-Datei könnte folgendermaßen aussehen:

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

Das dortige Bindungselement gibt an, wem zugeordnet werden soll (in diesem Beispiel wird dieses Styling auf alle Schaltflächen angewendet, deren Namenseigenschaft auf "Schmutz" festgelegt wurde).

Und ein paar nützliche Links:

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

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

Quelle
Translate

Ich gehe wahrscheinlich eine Million Meilen in die falsche Richtung (aber ich bin nur jung: P). Sie konnten die Grafik jedoch nicht zu einem Bedienfeld und dann zu einem Mauslistener zum Grafikobjekt hinzufügen, damit Ihre Aktion ausgeführt wird, wenn der Benutzer auf der Grafik ist.

Quelle
Translate

Ich habe seit meinen frühen CS-Kursen keine SWING-Entwicklung mehr durchgeführt, aber wenn es nicht eingebaut wäre, könnten Sie es einfach erbenjavax.swing.AbstractButtonund erstellen Sie Ihre eigenen. Sollte ziemlich einfach sein, etwas mit dem vorhandenen Framework zu verbinden.

Quelle