Bonjour,
Je souhaite que le texte d'un JLabel s'affiche à la verticale.
Je ne souhaite pas me retrouver avec les lettres les unes sous les autres, mais avec le texte réellement à la verticale.
Quelqu'un aurait-il une idée à me soumettre ?
Merci.
Bonjour,
Je souhaite que le texte d'un JLabel s'affiche à la verticale.
Je ne souhaite pas me retrouver avec les lettres les unes sous les autres, mais avec le texte réellement à la verticale.
Quelqu'un aurait-il une idée à me soumettre ?
Merci.
Bonjour,
il me semble qu'un code source a été proposé pour faire ce que tu veux. C'est ici.
Je te remercie, je ne l'avais effectivement pas trouvé.
En fait, je cherchais une solution un peu plus générique.
A vrai dire, je ne souhaite pas effectuer une rotation d'un seul label, mais de tout un groupe, avec d'ailleurs un ensemble d'autres contrôles de type différents.
Fort de cet exemple, j'ai donc entrepris de l'appliquer à un JPanel (après tout, il hérite de JComponent lui aussi). Mais voilà, mes espoirs de voir tout le contenu de mon JPanel effectuer une rotation de 90° ne semblent pas vouloir se réaliser.
Il me semble assez suspect qu'une telle rotation d'éléments ne soit pas plus basique.
Quelqu'un aurait-il une idée pour ne pas avoir à se cogner tous les types d'objets ?
je vient de voir le code qui se trouve la :-)
http://www.developpez.net/forums/sho...80&postcount=5
le probleme quand ont fait ce genre de chose c'est qu'on limite trop les possibilite du Jlabel.
par exemple
si je met une taille de 300 a un label qui en a besoin que de 100 pour s'afficher et que je met l'alignement au centre. comment le label va s'afficher avec ce code? (il sera aligner au top parce que l'alignement n'est pas gerer dans le code ou bien j'ai pas fait tres attention parce que je connait pas la classe ParameterUI et j'ai pas ete plus loin :-) )
si je met un Insets au label c'est pas gerer non plus
si le label est .setEnabled(false) il sera afficher de la meme facon qu'un label .setEnabled(true)
...
quand on veut faire ce genre de chose, normalement on joue sur le (look and) feel en creant son propre UI :-) (c'est juste une common practise personne est obliger )
bon je viens d'en faire un rapidement et un peu commenter (comme j'en aurai aussi besoin un bientot :o) )
c'est quick (but no so dirty code) et tout n'est pas encore terminer. je terminerai une autre fois.
j'ai essayer de garder les meme nom de variables que dans BasicLabelUI. tu peut toujours aller voir dans cette classe si tu comprend pas un truc ou me demander :-)) .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.plaf.basic.BasicLabelUI; /** * todo add a description and how to use this class * <code> * JLabel myLabel = new JLabel("some text"); * myLabel.setUI(new VerticalLabelUI(VerticalLabelUI.Direction.CLOCKWISE)); * someContainer.add(myLabel); * </code> * <p/> * todo add restrictions notes (does not support all alphabets...) or * implement them. * * @author bebe * @version draft */ public class VerticalLabelUI extends BasicLabelUI { /** * Direction in which the label's text will be rotated. * <ul> * <li>CLOCKWISE</li> * <li>COUNTERCLOCKWISE</li> * </ul> */ public enum Direction {CLOCKWISE, COUNTERCLOCKWISE} /** * * The default <code>BasicLabelUI</code> instance. This field might * not be used. To change the default instance use a subclass which * overrides the <code>createUI</code> method, and place that class * name in defaults table under the key "LabelUI". */ static { labelUI = new VerticalLabelUI(Direction.COUNTERCLOCKWISE); } /* 90° */ private final double NINETY_DEGREES = Math.PI / 2; /* see BasicLabelUI for description of these fields. I kept the same names.*/ private static Rectangle paintIconR = new Rectangle(); private static Rectangle paintTextR = new Rectangle(); private static Rectangle paintViewR = new Rectangle(); private static Insets paintViewInsets = new Insets(0, 0, 0, 0); /** * Direction how text will be rotated (clcokwise or counterclockwise ? */ protected Direction direction; /** * Create a (look and) feel object to render labels containing vertical * text. * * @param direction */ public VerticalLabelUI(Direction direction) { super(); this.direction = direction; } /* * the dimension returned are inversed !!! * (that's what we expected, so if you want to change this, do it carefully) */ @Override public Dimension getPreferredSize(JComponent c) { Dimension dim = super.getPreferredSize(c); /* prefered width is computed by the parent UI and we just return it parent width is our height and we compute our width using label's fontmetrics. remember the label is rotated this is why it's turned around. */ FontMetrics fm = c.getFontMetrics(c.getFont()); int height = fm.getHeight() + fm.getAscent() + fm.getDescent(); /*todo {check this dim.height: wrong value returned by super.getPreferedSize(c) in all likelihood it's depending on the (default) Locale. */ return new Dimension(height, dim.width); } /** * Javadoc copied from BasicLabelUI.paint * Paint the label text in the foreground color, if the label * is opaque then paint the entire background with the background * color. The Label text is drawn by paintEnabledText() or * paintDisabledText(). The locations of the label parts are computed * by layoutCL. * * @see #paintEnabledText * @see #paintDisabledText * @see #layoutCL */ @Override public void paint(Graphics g, JComponent c) { /* inspired by BasicLabelUI#paint*/ JLabel label = (JLabel) c; String text = label.getText(); Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon(); if ((icon == null) && (text == null)) { return; } FontMetrics fm = g.getFontMetrics(); paintViewInsets = c.getInsets(paintViewInsets); paintViewR.y = paintViewInsets.top; paintViewR.x = paintViewInsets.left; /* as the label is rotated, height and width are inversed. */ paintViewR.height = c.getWidth() - (paintViewInsets.left + paintViewInsets.right); paintViewR.width = c.getHeight() - (paintViewInsets.top + paintViewInsets.bottom); paintTextR.x = 0; paintTextR.y = 0; paintTextR.width = 0; paintTextR.height = 0; paintIconR.x = 0; paintIconR.y = 0; paintIconR.width = 0; paintIconR.height = 0; String clippedText = layoutCL(label, fm, text, icon, paintViewR, paintIconR, paintTextR); Graphics2D g2d = (Graphics2D) g; AffineTransform tr = g2d.getTransform(); if (direction == Direction.CLOCKWISE) { g2d.rotate(NINETY_DEGREES); g2d.translate(0, -c.getWidth()); } else { g2d.rotate(-NINETY_DEGREES); g2d.translate(-c.getHeight(), 0); } if (icon != null) { icon.paintIcon(c, g, paintIconR.x, paintIconR.y); } if (text != null) { int textX = paintTextR.x; int textY = paintTextR.y + fm.getAscent() + fm.getDescent(); if (label.isEnabled()) { paintEnabledText(label, g, clippedText, textX, textY); } else { paintDisabledText(label, g, clippedText, textX, textY); } } g2d.setTransform(tr); } }
et pour tester
(moi j'aurai besoin d'un vertical label avec une icone c'est pour ca que j'ai aussi pris en compte l'icone ;-) )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 import java.awt.EventQueue; import java.awt.GridBagLayout; import java.awt.Font; import java.net.URL; import java.io.IOException; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.ImageIcon; import javax.swing.Icon; import javax.swing.SwingConstants; import javax.imageio.ImageIO; /** * @author beb * */ public class VerticalUITester { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { JFrame f = new JFrame("Vertical Label Test"); f.setLayout(new GridBagLayout()); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel myVerticalLabel = null; try { Icon icon = new ImageIcon(ImageIO.read(new URL("http://java.developpez.com/img/small_faq_java.gif"))); myVerticalLabel = new JLabel("مرحبا", icon, SwingConstants.CENTER); myVerticalLabel.setFont(new Font("Lucida Sans", Font.PLAIN, 60)); myVerticalLabel.setUI(new VerticalLabelUI(VerticalLabelUI.Direction.CLOCKWISE)); f.add(myVerticalLabel); myVerticalLabel = new JLabel("صباح الخير", icon, JLabel.LEFT); myVerticalLabel.setFont(new Font("Lucida Sans", Font.PLAIN, 60)); myVerticalLabel.setUI(new VerticalLabelUI(VerticalLabelUI.Direction.COUNTERCLOCKWISE)); f.add(myVerticalLabel); } catch (IOException e) { e.printStackTrace(); } f.setSize(400, 300); f.setVisible(true); } }); } }
je vient de voir l'autre message avant le mien![]()
j'avait pas encore vu que tu voulait faire une rotation de tout un Panel.
je crois (je peut me tromper) que faire rotationer un panel de 90% d'un coup c'est pas possible de maniere simple. j'ai jamait essayer et je croit que c'est un joli challenge![]()
deja il te faut de bonne base sur la creation d'UI pour faire ca (un peu comme je vient de faire mais pour tes autre composant).
ca va en faire du code![]()
![]()
![]()
mais moi je voit pas a quoi ca sert.
de droite a gauche et de gauche a droite je peut comprendre.
mais j'immagine mal un combobox vertical ou un jtable vertical :-S
t'a pas une image de ce que tu veut en fait?
Pour la classe de GENERYS, elle fonctionne belle et bien. Merci à lui, et à vous deux l'info.
En fait, je ne suis pas convaincu que ParameterUI ne soit pas une classe à lui.
Le deux trois petites modif suivantes permettent de la rendre autonome.
Mais je dois admettre que ta solution semble plus prompte à être généralisée à d'autres contrôles. Je vais donc me pencher dessus avec grand intérêt.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 import javax.swing.*; import java.awt.*; /** * Permet d'afficher un JLabel vertical */ public class JLabelVertical extends JLabel { public void paintComponent(Graphics g) { Graphics2D graphics2D = (Graphics2D) g; super.paintComponents(g); graphics2D.translate(0, getHeight()); graphics2D.rotate(-Math.PI/2); graphics2D.setFont(this.getFont()); graphics2D.drawString(this.getText(), 0 , (getHeight()-getStringHeight())/2); } /* * (non-Javadoc) * @see java.awt.Component#getPreferredSize() */ public Dimension getPreferredSize() { Dimension dimension = new Dimension(getStringHeight(), getStringWidth()); return dimension; } /* * (non-Javadoc) * @see java.awt.Component#getMinimumSize() */ public Dimension getMinimumSize() { return getPreferredSize(); } private int getStringWidth() { FontMetrics metrics = getFontMetrics(this.getFont()); int width = metrics.stringWidth(this.getText()); return width; } private int getStringHeight() { FontMetrics metrics = getFontMetrics(this.getFont()); int height = metrics.getHeight(); return height; } /** Creates a new instance of JLabelVertical */ public JLabelVertical(String txt) { this.setText(txt); } /** Creates a new instance of JLabelVertical */ public JLabelVertical() { } /** * @param args the command line arguments */ public static void main(String[] args) { JFrame jf = new JFrame(); JLabelVertical jlv = new JLabelVertical(); jlv.setText("Toto"); jlv.setFont(new java.awt.Font("Courier New", 0, 10)); jf.setContentPane(new JPanel()); jf.getContentPane().add(jlv); jf.setSize(50,100); jf.setVisible(true); } }
Pour faire bref, je ne compte effectivement pas appliquer cela à n'importe quels contrôles. Dans mon cas, je me contenterai de quelques labels, zones textes, et boutons. A l'occasion, je posterai une image de ce que je serai parvenu à réaliser![]()
A priori, pour les composants passifs, c'est relativement simple. Il te suffit de créer l'image et de la tourner.
Pour les boutons, c'est plus tendu, tu devra passer par l'UI (il faut faire tourner le texte et l'icône avec leurs positions respectives, mais garder le comportement normal des borders et du background).
Pour les composants texte (c'est ma bête noire) à moins de t'y connaître sérieusement, tu vas avoir besoin de temps.
Partager