Risposte:
Quando stavo imparando Java per la prima volta, dovevamo creare Yahtzee e ho pensato che sarebbe stato interessante creare componenti e contenitori Swing personalizzati invece di disegnare tutto su uno JPanel
. Il vantaggio di estendere i Swing
componenti, ovviamente, è avere la possibilità di aggiungere il supporto per le scorciatoie da tastiera e altre funzionalità di accessibilità che non puoi fare semplicemente facendo in modo che un paint()
metodo stampi una bella immagine. Tuttavia, potrebbe non essere fatto nel modo migliore, ma potrebbe essere un buon punto di partenza per te.
Modifica 8/6 - Se non era evidente dalle immagini, ogni dado è un pulsante su cui puoi fare clic. Questo lo sposterà in DiceContainer
basso. Guardando il codice sorgente puoi vedere che ogni pulsante Die viene disegnato dinamicamente, in base al suo valore.
Ecco i passaggi di base:
JComponent
super()
nei tuoi costruttoriMouseListener
Mettilo nel costruttore:
enableInputMethods(true);
addMouseListener(this);
Ignora questi metodi:
public Dimension getPreferredSize()
public Dimension getMinimumSize()
public Dimension getMaximumSize()
Sostituisci questo metodo:
public void paintComponent(Graphics g)
La quantità di spazio con cui devi lavorare quando disegni il tuo pulsante è definita da getPreferredSize()
, assumendo getMinimumSize()
e getMaximumSize()
restituendo lo stesso valore. Non ho sperimentato molto con questo ma, a seconda del layout che usi per la tua GUI, il tuo pulsante potrebbe apparire completamente diverso.
E infine, il codice sorgente . Nel caso mi sia perso qualcosa.
Sì, è possibile. Uno dei principali vantaggi dell'utilizzo di Swing è la facilità con cui i controlli astratti possono essere creati e manipolati.
Ecco un modo rapido e sporco per estendere la classe JButton esistente per disegnare un cerchio a destra del testo.
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);
}
}
Notare che sovrascrivendo paintComponent che il contenuto del pulsante può essere modificato, ma che il bordo è disegnato dal metodo paintBorder . Anche il metodo getPreferredSize deve essere gestito per supportare dinamicamente le modifiche al contenuto. È necessario prestare attenzione quando si misurano le metriche dei caratteri e le dimensioni dell'immagine.
Per creare un controllo su cui puoi fare affidamento, il codice precedente non è l'approccio corretto. Dimensioni e colori sono dinamici in Swing e dipendono dall'aspetto e dalla sensazione utilizzati. Anche l' aspetto Metal predefinito è cambiato nelle versioni di JRE. Sarebbe meglio implementare AbstractButton e conformarsi alle linee guida stabilite dall'API Swing. Un buon punto di partenza è guardare le classi javax.swing.LookAndFeel e 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
Comprendere l'anatomia di LookAndFeel è utile per scrivere i controlli: Creazione di un aspetto personalizzato
Puoi sempre provare il look & feel del Synth. Fornisci un file xml che funge da una sorta di foglio di stile, insieme a tutte le immagini che desideri utilizzare. Il codice potrebbe essere simile a questo:
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);
}
Da lì, vai avanti e aggiungi il tuo JButton come faresti normalmente. L'unico cambiamento è che si utilizza il metodo setName (stringa) per identificare a cosa deve mappare il pulsante nel file xml.
Il file xml potrebbe essere simile a questo:
<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>
L'elemento bind qui specifica a cosa mappare (in questo esempio, applicherà quello stile a tutti i pulsanti la cui proprietà name è stata impostata su "dirt").
E un paio di link utili:
http://javadesktop.org/articles/synth/
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html
Probabilmente sto andando un milione di miglia nella direzione sbagliata (ma sono solo giovane: P). ma non potresti aggiungere la grafica a un pannello e poi un mouselistener all'oggetto grafico in modo che quando l'utente sul grafico la tua azione sia eseguita.
Non ho sviluppato SWING dai miei primi corsi CS, ma se non fosse stato integrato potresti semplicemente ereditare javax.swing.AbstractButton
e creare il tuo. Dovrebbe essere abbastanza semplice collegare qualcosa insieme al loro framework esistente.