2008-08-05 16 views
85

Gibt es eine Möglichkeit, eine JButton mit Ihrer eigenen Schaltfläche Grafik und nicht nur mit einem Bild in der Schaltfläche erstellen?Erstellen eines benutzerdefinierten JButton in Java

Wenn nicht, gibt es eine andere Möglichkeit, eine benutzerdefinierte JButton in Java zu erstellen?

Antwort

85

Als ich das erste Java wurde lernen wir Yahtzee machen musste, und ich dachte, es wäre cool zu Erstellen Sie benutzerdefinierte Swing-Komponenten und Container statt nur alles auf eine Zeichnung JPanel. Der Vorteil der Erweiterung von Swing Komponenten ist natürlich die Möglichkeit, Unterstützung für Tastaturkurzbefehle und andere Eingabehilfefunktionen hinzuzufügen, die Sie nicht einfach mit einer paint() Methode ein schönes Bild drucken können. Es ist vielleicht nicht der beste Weg, aber es kann ein guter Ausgangspunkt für Sie sein.

Edit 8/6 - Wenn es nicht aus den Bildern ersichtlich war, ist jeder Würfel ein Knopf, den Sie anklicken können. Dies wird es auf die DiceContainer unten verschieben. Wenn Sie den Quellcode betrachten, können Sie sehen, dass jede Schaltfläche "Die" basierend auf ihrem Wert dynamisch gezeichnet wird.

alt text
alt text
alt text

Hier sind die grundlegenden Schritte:

  1. Erstellen Sie eine Klasse, die JComponent
  2. Anruf Mutter Konstruktor super() in Ihren Konstrukteuren
  3. Stellen Sie sicher, Klasse erweitert implementiert MouseListener
  4. Setzen dies im Konstruktor:

    enableInputMethods(true); 
    addMouseListener(this); 
    
  5. Aufschalten der folgenden Methoden:

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

    public void paintComponent(Graphics g) 
    

Die Menge des s Schritt, mit dem Sie arbeiten müssen, wenn Sie Ihre Schaltfläche zeichnen, ist definiert durch getPreferredSize(), vorausgesetzt, getMinimumSize() und getMaximumSize() geben den gleichen Wert zurück. Ich habe nicht zu viel damit experimentiert, aber je nach dem Layout, das Sie für Ihre GUI verwenden, könnte Ihre Schaltfläche völlig anders aussehen.

Und schließlich die source code. Falls ich etwas verpasst habe.

+1

Hallo, erstmal danke für den Code! Ich würde vorschlagen, einen 'setActionComm (String Command)' zu Ihrem Code hinzuzufügen. Dies ist eine der Möglichkeiten, Ereignisse in Swing zu filtern. (Aber dann können Sie argumentieren, dass es 1001 Dinge gibt, die hinzugefügt werden könnten, um die Dinge etwas besser zu machen: P) –

+1

Kannst du den ganzen Code hier einfügen? –

+0

Um einen Würfel zu erstellen, den Sie drücken können, können Sie tatsächlich einen einfachen alten JButton verwenden (anstatt eine benutzerdefinierte JComponent zu unterklassifizieren oder zu erstellen), indem Sie die setIcon/setPressedIcon- und andere Icon-Funktionen in JButton verwenden. – ControlAltDel

6

Ich habe keine SWING-Entwicklung seit meinen frühen CS-Klassen, aber wenn es nicht eingebaut war, könnten Sie einfach javax.swing.AbstractButton erben und erstellen Sie Ihre eigenen. Sollte ziemlich einfach sein, etwas mit ihrem vorhandenen Rahmen zusammen zu verdrahten.

12

Sie könnten immer versuchen, den Synth-Look & fühlen. Sie stellen eine XML-Datei zur Verfügung, die zusammen mit allen Bildern, die Sie verwenden möchten, als eine Art Stylesheet fungiert. 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 gehen Sie weiter und fügen Sie Ihr JButton wie Sie normalerweise würden. Die einzige Änderung besteht darin, dass Sie die Methode setName (string) verwenden, um zu ermitteln, welcher Schaltfläche die Schaltfläche in der XML-Datei zugeordnet werden soll.

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 Bindeelement dort gibt, was zur Karte (in diesem Beispiel ist es, dass Styling auf alle Schaltflächen, deren Name-Eigenschaft festgelegt wurde, gilt auf „Schmutz ").

Und ein paar nützliche Links:

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

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

32

Ja, das ist möglich. Eines der wichtigsten Argumente für die Verwendung von Swing ist die Leichtigkeit, mit der die abstrakten Steuerelemente erstellt und manipuliert werden können.

Hier ist eine schnelle und schmutzige Möglichkeit, die vorhandene JButton-Klasse zu erweitern, um einen Kreis auf der rechten Seite des Textes 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; 
    } 

    /*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 von der Methode paintBorder gemalt. Die Methode getPreferredSize muss auch verwaltet werden, um Änderungen am Inhalt dynamisch zu unterstützen. Beim Messen von Schriftmetriken und Bilddimensionen ist Vorsicht geboten.

Zum Erstellen eines Steuerelements, auf das Sie sich verlassen können, ist der obige Code nicht der richtige Ansatz. Abmessungen und Farben sind dynamisch in Swing und hängen vom verwendeten Look and Feel ab. Selbst der Standard Metal Aussehen hat sich über JRE-Versionen geändert. Es wäre besser, AbstractButton zu implementieren und den Richtlinien der Swing API zu entsprechen. Ein guter Ausgangspunkt ist die 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 des LookAndFeel zu verstehen, ist für das Schreiben von Kontrollen nützlich: Creating a Custom Look and Feel

8

Ich gehe wahrscheinlich eine Million Meilen in die falsche direkte (aber ich bin nur jung: P). Aber du kannst die Grafik nicht zu einem Panel und dann einen Mauslistener zum Grafikobjekt hinzufügen, so dass wenn der Benutzer auf der Grafik deine Aktion durchgeführt wird.

+1

Das würde funktionieren, aber Ich würde es vorziehen, den Standard-JButton zu verwenden, als wenn ich einen meiner Button-Typen erstellen würde. – Anton