Réponses:
Quand j'ai appris Java pour la première fois, nous devions créer Yahtzee et j'ai pensé que ce serait cool de créer des composants et des conteneurs Swing personnalisés au lieu de tout dessiner sur un seul JPanel
. L'avantage d'étendre les Swing
composants, bien sûr, est d'avoir la possibilité d'ajouter la prise en charge des raccourcis clavier et d'autres fonctionnalités d'accessibilité que vous ne pouvez pas faire simplement en demandant à une paint()
méthode d'imprimer une jolie image. Cela peut ne pas être fait de la meilleure façon, mais cela peut être un bon point de départ pour vous.
Edit 8/6 - Si ce n'était pas apparent sur les images, chaque Die est un bouton sur lequel vous pouvez cliquer. Cela le déplacera vers le DiceContainer
dessous. En regardant le code source, vous pouvez voir que chaque bouton Die est dessiné dynamiquement, en fonction de sa valeur.
Voici les étapes de base:
JComponent
super()
dans vos constructeursMouseListener
Mettez ceci dans le constructeur:
enableInputMethods(true);
addMouseListener(this);
Remplacez ces méthodes:
public Dimension getPreferredSize()
public Dimension getMinimumSize()
public Dimension getMaximumSize()
Remplacez cette méthode:
public void paintComponent(Graphics g)
La quantité d'espace avec laquelle vous devez travailler lorsque vous dessinez votre bouton est définie par getPreferredSize()
, en supposant getMinimumSize()
et en getMaximumSize()
renvoyant la même valeur. Je n'ai pas trop expérimenté cela mais, en fonction de la mise en page que vous utilisez pour votre interface graphique, votre bouton peut être complètement différent.
Et enfin, le code source . Au cas où j'aurais raté quelque chose.
Oui, c'est possible. L'un des principaux avantages de l'utilisation de Swing est la facilité avec laquelle les contrôles abstraits peuvent être créés et manipulés.
Voici un moyen rapide et sale d'étendre la classe JButton existante pour dessiner un cercle à droite du texte.
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);
}
}
Notez qu'en substituant paintComponent que le contenu du bouton peut être modifié, mais que la bordure est peinte par la méthode paintBorder . Le getPreferredSize méthode doit également être gérée afin de prendre en charge dynamiquement les modifications du contenu. Des précautions doivent être prises lors de la mesure des mesures de police et des dimensions de l'image.
Pour créer un contrôle sur lequel vous pouvez compter, le code ci-dessus n'est pas la bonne approche. Les dimensions et les couleurs sont dynamiques dans Swing et dépendent de l'aspect et de la sensation utilisés. Même l' apparence Metal par défaut a changé dans les versions de JRE. Il serait préférable d'implémenter AbstractButton et de se conformer aux directives définies par l'API Swing. Un bon point de départ est de regarder les classes javax.swing.LookAndFeel et 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
Comprendre l'anatomie de LookAndFeel est utile pour écrire des commandes: Création d'une apparence et d'une sensation personnalisées
Vous pouvez toujours essayer le look & feel Synth. Vous fournissez un fichier xml qui agit comme une sorte de feuille de style, avec toutes les images que vous souhaitez utiliser. Le code pourrait ressembler à ceci:
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);
}
À partir de là, continuez et ajoutez votre JButton comme vous le feriez normalement. Le seul changement est que vous utilisez la méthode setName (string) pour identifier à quoi le bouton doit être mappé dans le fichier xml.
Le fichier xml pourrait ressembler à ceci:
<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'élément bind spécifie à quoi mapper (dans cet exemple, il appliquera ce style à tous les boutons dont la propriété name a été définie sur "dirt").
Et quelques liens utiles:
http://javadesktop.org/articles/synth/
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html
Je vais probablement un million de kilomètres dans la mauvaise direction directe (mais je ne suis que jeune: P). mais ne pourriez-vous pas ajouter le graphique à un panneau puis une souris à l'objet graphique de sorte que lorsque l'utilisateur sur le graphique, votre action soit préformée.
Je n'ai pas fait de développement SWING depuis mes premières classes CS, mais s'il n'était pas intégré, vous pourriez simplement hériter javax.swing.AbstractButton
et créer les vôtres. Cela devrait être assez simple de câbler quelque chose avec leur cadre existant.