Antworten:
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 zeichnen JPanel
. Der Vorteil der Erweiterung von Swing
Komponenten besteht natürlich darin, dass Tastaturkürzel und andere Eingabehilfen unterstützt werden können, die Sie nicht einfach durch paint()
Drucken eines hübschen Bilds durch eine Methode ausführen können. 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 nach DiceContainer
unten verschoben . Wenn Sie sich den Quellcode ansehen, sehen Sie, dass jede Die-Schaltfläche basierend auf ihrem Wert dynamisch gezeichnet wird.
Hier sind die grundlegenden Schritte:
JComponent
super()
in Ihren Konstruktoren aufMouseListener
Geben Sie dies in den Konstruktor ein:
enableInputMethods(true);
addMouseListener(this);
Überschreiben Sie diese Methoden:
public Dimension getPreferredSize()
public Dimension getMinimumSize()
public Dimension getMaximumSize()
Überschreiben Sie diese Methode:
public void paintComponent(Graphics g)
Die Menge an Speicherplatz, mit der Sie beim Zeichnen Ihrer Schaltfläche arbeiten müssen, wird definiert getPreferredSize()
, indem derselbe Wert angenommen getMinimumSize()
und getMaximumSize()
zurückgegeben wird. 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 der Quellcode . Für den Fall, dass ich etwas verpasst habe.
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;
}
/*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 Überschreiben von paintComponent der Inhalt der Schaltfläche geändert werden kann, der Rahmen jedoch mit der paintBorder- Methode gezeichnet wird. Die Methode getPreferredSize muss ebenfalls 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 das Standard- Metal- Aussehen hat sich in den JRE-Versionen geändert. Es wäre besser, AbstractButton zu implementieren und die Richtlinien der Swing-API einzuhalten. Ein guter Ausgangspunkt ist ein Blick auf die Klassen javax.swing.LookAndFeel und javax.swing.UIManager .
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
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, was zugeordnet werden soll (in diesem Beispiel wird dieses Styling auf alle Schaltflächen angewendet, deren Namenseigenschaft 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
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.
Ich habe seit meinen frühen CS-Kursen keine SWING-Entwicklung mehr durchgeführt, aber wenn es nicht eingebaut wäre, könnten Sie einfach javax.swing.AbstractButton
Ihre eigenen erben und erstellen. Sollte ziemlich einfach sein, etwas mit dem vorhandenen Framework zu verbinden.