Erstellen einer benutzerdefinierten JButton in Java

stimmen
86

Gibt es eine Möglichkeit ein erstellen JButtonmit Ihrer eigenen Knopf Grafik und nicht nur mit einem Bild in der Schaltfläche?

Wenn nicht, gibt es eine andere Art und Weise eine benutzerdefinierte erstellen JButtonin Java?

Veröffentlicht am 05/08/2008 um 13:15
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
85

Als ich zuerst Java lernen mussten wir Yahtzee machen und ich dachte , es wäre cool , benutzerdefinierte Swing - Komponenten und Container statt nur alles Zeichnung auf einem erstellen JPanel. Der Vorteil der Verlängerung SwingKomponenten, natürlich, ist es, die Fähigkeit zu haben , Unterstützung für Funktionen Tastaturkürzel und andere Zugänglichkeit hinzuzufügen , die Sie nicht nur , indem er ein tun können paint()Verfahren ein hübsches Bild drucken. Es ist vielleicht nicht der beste Weg , aber getan werden, aber es kann ein guter Ausgangspunkt für Sie sein.

Bearbeiten 8/6 - Wenn es nicht offensichtlich aus den Bildern war, jede Die ist eine Schaltfläche Sie klicken können. Dies wird es dem bewegen DiceContainerunten. Mit Blick auf den Quellcode können Sie sehen , dass jede Taste Die dynamisch gezeichnet wird, basierend auf seinen Wert.

Alt-Text
Alt-Text
Alt-Text

Hier sind die grundlegenden Schritte:

  1. Erstellen Sie eine Klasse, die sich JComponent
  2. Call Mutter Konstruktor super()in Ihrer Konstrukteure
  3. Stellen Sie sicher, dass Sie Klasse implementiert MouseListener
  4. Setzen Sie dieses in den Konstruktor:

    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)
    

Die Menge an Speicherplatz haben , mit denen Sie arbeiten bei der Erstellung Ihrer Taste ist definiert durch getPreferredSize(), unter der Annahme , getMinimumSize()und getMaximumSize()den gleichen Wert zurück. Ich habe nicht zu viel mit diesen experimentiert , sondern je nach dem Layout , das Sie für Ihre GUI benutzen , um Ihre Schaltfläche ganz anders aussehen könnte.

Und schließlich der Quellcode . Für den Fall , vermisste ich nichts.

Beantwortet am 05/08/2008 um 14:03
quelle vom benutzer

stimmen
32

Ja, das ist möglich. Einer der wichtigsten Profis für Swing verwendet, ist die Leichtigkeit, mit der die abstrakten Kontrollen erstellt und manipuliert werden.

Hier ist eine schnelle und schmutzige Art und Weise die bestehende JButton-Klasse zeichnen Sie einen Kreis auf der rechten Seite des Textes zu erweitern.

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

}

Beachten Sie, dass durch zwingende paintcomponent , dass der Inhalt der Taste kann verändert werden, sondern dass die Grenze wird durch die gemalten paintBorder Methode. Die getPreferredSize Methode muss auch verwaltet , um werden , um dynamisch Änderungen an den Inhalten zu unterstützen. Pflege muss getroffen werden , wenn Fontmetriken und Bildabmessungen zu messen.

Für eine Steuerung zu schaffen , die Sie sich verlassen können, ist der obige Code nicht der richtige Ansatz. Maße und Farben sind dynamisch in Swing und sind abhängig von der Optik und Haptik verwendet werden. Selbst der Standard - Metall - Look hat über JRE - Versionen geändert. Es wäre besser, zu implementieren Abstract und die Richtlinien festgelegten von dem Swing - API entspricht. Ein guter Ausgangspunkt ist an den suchen javax.swing.LookAndFeel und javax.swing.UIManager Klassen.

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

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

Die Anatomie der LookAndFeel zu verstehen , ist nützlich für das Schreiben von Kontrollen: Erstellen eines benutzerdefinierten Look and Feel

Beantwortet am 05/08/2008 um 13:53
quelle vom benutzer

stimmen
12

Sie könnten der Synth Look & Feel immer versuchen. Sie bieten eine XML-Datei, die als eine Art Sheet wirkt, zusammen mit allen Bildern, die Sie verwenden möchten. Der Code könnte wie folgt 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 geht auf und fügen Sie Ihre JButton wie gewohnt. Die einzige Änderung ist, dass Sie die setName (string) Methode verwenden, um herauszufinden, was die Taste, um in der XML-Datei zuordnen sollte.

Die XML-Datei könnte wie folgt 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 Bind-Element gibt es was auf die gemappt (in diesem Beispiel wird es, dass Styling auf alle Tasten anwenden Eigenschaft, deren Name auf „Schmutz“ gesetzt wurde).

Und ein paar nützliche Links:

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

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

Beantwortet am 05/08/2008 um 13:47
quelle vom benutzer

stimmen
8

Ich bin wahrscheinlich eine Million Meilen in den falschen direkten gehen (aber ich bin nur junge: P). konnte aber nicht, dass Sie die Grafik zu einem Panel hinzufügen und dann einen Mouselistener an das grafische Objekt, so dass, wenn der Benutzer auf die Grafik, die Aktion vorgeformt ist.

Beantwortet am 20/08/2008 um 16:48
quelle vom benutzer

stimmen
6

Ich habe nicht SWING Entwicklung seit meinen frühen CS-Klassen gemacht, aber wenn es nicht in dir gebaut wurde, kann nur javax.swing.AbstractButton erben und eigene erstellen. Sollte ziemlich einfach etwas zusammen mit ihrem bestehenden Rahmen verdrahten.

Beantwortet am 05/08/2008 um 13:30
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more