Boîte à outils graphique = ensemble de classes Java

publicité
Boîtes à outils graphiques
Faire une interface graphique avec Java2d
et Swing
• Boîte à outils graphique = ensemble
de classes Java permettant de
développer des interfaces hommemachine
• Il faut :
– Pouvoir définir une apparence graphique
– Écouter les actions de l’utilisateur
Dans ce cours…
• Nous utilisons les boîtes à outils AWT
(Abstract Window Toolkit) et Swing.
• La plupart des classes de Swing ont
leur équivalent en AWT
=> Alors pourquoi AWT+Swing et
non pas simplement AWT ?
AWT vs. Swing
Chaque plateforme (Windows, Unix,
Mac…) dispose de ses propres
éléments graphiques (fenêtres,
boutons, etc.)
Windows 2000
Mac OS X
AWT vs. Swing
Avec Swing, on peut définir le "look
and feel" de son interface.
=> Le rendu sera le même quelle que
soit la plateforme
Windows 2000
Définir le rendu graphique d’une interface
Mac OS X
Hiérarchie de composants graphiques
• Les éléments d’une interface sont organisés selon
une hiérarchie.
• La racine est un composant conteneur "toplevel"
• Les nœuds sont des composants conteneurs
• Les feuilles sont de simples composants ou des
composants conteneurs
Top-level conteneurs
• JFrame
(application)
• JDialog
(dépendant d'un autre top-level)
• JApplet
(applet)
Nœuds conteneurs intermédiaires
On utilise des composants de la classe
:
- javax.swing.JPanel
- javax.swing.JScrollPane
-…
Les feuilles
• Dans un premier temps, nous nous
intéressons aux composants
prédéfinis de swing (Swing widgets)
• Nous verrons plus tard comment
faire nos propres composants
Les Swing widgets
Plus d’exemples
• Voir :
http://java.sun.com/docs/books/tutorial/uiswing/components/components.html
JButton
• Quelques exemples :
javax.swing.JButton
javax.swing.JComponent
JLabel (avec ou
sans image)
javax.swing.JCheckbox
JTextField (+JPasswordField + JFormatedTextField)
Plus d’exemples
Exemple d’une hiérarchie
Javax.swing.JFrame
Conteneur
de top-level
JSlider
JComboBox
JSpinner
Javax.swing.JPanel
Javax.swing.JComponent
JList
Javax.swing.JButton
Javax.swing.JCheckbox
JProgressBar
Exemple d’une hiérarchie
JFrame frame = new JFrame("Example JFrame");
Container container1 = frame.getContentPane();
JPanel bluePanel = new JPanel();
bluePanel.setBackground(new Color(0, 0, 200));
JTextField component1 = new JTextField("component1");
JCheckBox
component2 = new JCheckBox("component2");
JButton component3 = new JButton("component3");
GridLayout layoutBluePanel = new GridLayout(2, 1);
layoutBluePanel.setVgap(3);
bluePanel.setLayout(layoutBluePanel);
container1.add(bluePanel);
container1.add(component3);
bluePanel.add(component1);
bluePanel.add(component2);
frame.pack();
frame.setVisible(true);
Et la mise en page ?
• Comment obtenir cette organisation
spatiale ?
=> Il faut spécifier la mise en page
des différents nœuds et feuilles.
La mise en page : les layouts managers
Un layout manager est un objet qui,
associé à un conteneur C, détermine
la taille et la position des composants
graphiques qui appartiennent à C.
Conteneur
de top-level
LayoutManager
Les layout managers : BorderLayout
C’est le layout manager par défaut
pour les conteneurs de top-level.
• Cinq Fils
–
–
–
–
–
Nord
Est
Sud
Ouest
Centre
• Nord prend toute la largeur disponible (getWidth())
mais juste sa hauteur préférée (getPreferredSize())
• … ainsi de suite et Center prend tout ce qui reste
container.add(myComponent, BorderLayout.NORTH);
Les layout managers : layout absolu
JFrame frame = new JFrame("Example JFrame");
frame.setSize(280, 130);
Container container1 = frame.getContentPane();
container1.setLayout(null);
JTextField component1 = new JTextField("component1");
component1.setBounds(
25,
10,
(int)component1.getPreferredSize().getWidth(),
(int)component1.getPreferredSize().getHeight());
JCheckBox
component2 = new JCheckBox("component2");
component2.setBounds(
100,
60,
(int)component2.getPreferredSize().getWidth(),
(int)component2.getPreferredSize().getHeight());
frame.getContentPane().add(component1);
frame.getContentPane().add(component2);
frame.setVisible(true);
Reprenons notre exemple
JFrame frame = new JFrame("Example JFrame");
Container container1 = frame.getContentPane();
JPanel bluePanel = new JPanel();
bluePanel.setBackground(new Color(0, 0, 200));
JTextField component1 = new JTextField("component1");
JCheckBox
component2 = new JCheckBox("component2");
JButton component3 = new JButton("component3");
GridLayout layoutBluePanel = new GridLayout(2, 1);
layoutBluePanel.setVgap(3);
bluePanel.setLayout(layoutBluePanel);
container1.add(bluePanel, BorderLayout.CENTER);
container1.add(component3, BorderLayout.EAST);
bluePanel.add(component1);
bluePanel.add(component2);
frame.pack();
frame.setVisible(true);
pack… qu’est-ce que c’est ?
frame.pack();
• Chaque composant a une dimension
préferrée (getPreferredSize())
• La méthode pack exécute la mise en
page en fonction des layouts
managers des conteneurs et des
dimensions préferrées des
composants feuilles.
La crème du layout manager : Le GridBagLayout
• C’est le plus flexible (on peut
spécifier les espaces, comment se
passe le redimensionnement, etc.)
mais aussi le plus compliqué
Exemple au tableau :
Spécifier la dimension préferrée (ex : JScrollPane)
JTextArea textArea = new JTextArea();
textArea.setPreferredSize(new Dimension(400, 1000));
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(400, 400));
JFrame frame = new JFrame("Scrollable JPanel");
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
Attention : En général, on ne change pas
La dimension préferrée des Swing widgets
Application graphique : 2 processus
frame.setVisible(true);
Dès qu’une fenêtre est rendue visible,
le programme ne termine pas à la fin
du main.
Pour que le programme se termine
quand on ferme la fenêtre :
frame.setDefaultCloseOperation(
Jframe.EXIT_ON_CLOSE);
Définir le rendu graphique d’un composant
Définir le rendu graphique d’un composant
•
• Le rendu graphique des composants est assuré par le thread awt
(cf. cours suivant). Pour assurer la fluidité, Swing utilise un
mécanisme de double-buffering.
• Le thread awt se charge d’appeler repaint() sur les composants
quand cela est nécessaire : le composant devient visible, il est
redimensionné…repaint() appelle paint() dès que c’est possible.
On ne force pas un appel à paint(), on appelle repaint().
• Pour les composants standard, le rendu déjà défini par Swing, on
le redéfinit pas en général.
• Pour définir le rendu graphique d’un composant, on fait
généralement une sous-classe de JComponent ou Jpanel dans
laquelle on redéfinit la méthode paint.
Dessiner des primitives graphiques Java2D
public class MyComponent extends JPanel {
Image logo;
public MyComponent() {
Toolkit tk = Toolkit.getDefaultToolkit();
logo = tk.getImage("UPS11-logo.jpg");
try {
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(logo, 0);
tracker.waitForID(0);
} catch(Exception e) { e.printStackTrace(); }
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.fillOval(150, 250, 200, 100);
g2d.drawRect(200, 40, 100, 200);
g2d.drawString("Hello", 30, 300);
g2d.drawImage(logo, 0, 0, this);
}
}
(0, 0)
•
La méthode paint(Graphics g) permet de
récupérer un contexte graphique dans
lequel dessiner
Il faut caster en Graphics2D pour disposer
de toutes les fonctionnalités de la librairie
Java2D
public class MyComponent extends JPanel {
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
…
}
}
Le contexte du graphics2D
Le contexte graphique est défini par :
• des attributs de style :
- java.awt.Paint (ex: java.awt.Color…)
- java.awt.Stroke (ex:
java.awt.BasicStroke…)
- java.awt.Font
• des attributs géométriques :
- java.awt.geom.AffineTransform
• des attributs définissant la qualité :
- java.awt.RenderingHints
Le contexte du graphics2D
Des primitives plus évoluées
interface java.awt.Shape
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.RED);
g2d.fillOval(150, 250, 200, 100);
g2d.setStroke(new BasicStroke(4));
g2d.drawRect(200, 40, 100, 200);
Ex : Ellipse, Rectangle, Segments, Polylignes…
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("verdana", Font.ITALIC, 24));
g2d.drawString("Hello", 30, 300);
AffineTransform transf = new AffineTransform();
transf.translate(10, 20);
transf.rotate(Math.PI/4);
g2d.setTransform(transf);
g2d.drawImage(logo, 0, 0, this);
}
GeneralPath gp = new GeneralPath();
gp.moveTo(60, 30);
gp.lineTo(90, 60);
gp.lineTo(30, 60);
gp.closePath();
g2d.fill(gp);
Téléchargement