IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Java Discussion :

Problème de comportement de deriveFont


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Par défaut Problème de comportement de deriveFont
    Bonjour à tous !
    Je rencontre un souci plutôt étonnant. En effet, quand j'affiche un JLabel avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    JLabel test = new JLabel("Test");
    test.setFont(new Font(Font.SERIF, Font.BOLD, 50);
    test.setVerticalAlignment(SwingConstants.CENTER);
    ...
    Mon texte apparaît bien centré dans son JLabel.

    Mais lorsque je l'affiche avec ce code (qui me permet de définir ma propre police) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    JLabel test = new JLabel("Test");
    test.setFont(calibri.deriveFont(Font.BOLD, 50)); // J'ai créé la police calibri auparavant
    test.setVerticalAlignment(SwingConstants.CENTER);
    ...
    Le texte n'est pas vraiment centré. En fait c'est la ligne sur laquelle repose le texte qui est centrée. Du coup, dans les faits, mon texte est légèrement décentré vers le haut.

    Vous savez si on peut remédier à ça ?

    Merci d'avance !

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Les polices n'ont pas les mêmes caractéristiques (chasse, corps, œil, hampe, jambage, etc) et de plus un JLabel se dimensionne en fonction de ces métriques par rapport à un placement sur la ligne de base. Le centrage vertical se fait par rapport aux dimensions du JLabel, qui peuvent être également influencées par le composant d'agencement du conteneur, ainsi que sa position d'ailleurs.

    On voit mieux ce qu'il se passe avec un exemple (ici le même texte dans trois polices différentes, stylées différemment, mais de même corps) :

    Nom : Capture.JPG
Affichages : 230
Taille : 25,4 Ko

    Et j'affiche en console quelques informations :
    Label 1 
    Dimensions du label : 105 × 65
    Position de la ligne de base : 51
    Label 2 
    Dimensions du label : 104 × 61
    Position de la ligne de base : 43
    Label 3 
    Dimensions du label : 103 × 59
    Position de la ligne de base : 47
    
    Le code pour obtenir ce résultat :

    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
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.Point;
     
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
     
    public class JFontTest {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JPanel panel = new JPanel(new GridBagLayout()) {
    			protected void paintComponent(java.awt.Graphics g) {
    				super.paintComponent(g);
    				GridBagLayout layout = (GridBagLayout) this.getLayout();
    				Point p = layout.getLayoutOrigin();
    				int[][] ld = layout.getLayoutDimensions(); 
    				int w = 0;
    				int h = ld[1][0];
    				for(int i=0; i<ld[0].length; i++) {
    					w += ld[0][i];
    				}
    				g.setColor(Color.RED);
    				g.fillRect(p.x, p.y, w, h);
     
    			}
    		};
     
    		GridBagConstraints gbc = new GridBagConstraints();
    		gbc.insets = new Insets(5, 5, 5, 5);
     
    		JLabel label1 = new JLabel("testjl");
    		label1.setFont(new Font(Font.SERIF, Font.BOLD, 50));
    		label1.setVerticalAlignment(JLabel.CENTER);
    		label1.setBackground(Color.GREEN);
    		label1.setOpaque(true);
    		panel.add(label1, gbc);
    		JLabel label2 = new JLabel("testjl");
    		label2.setFont(new Font("Calibri", Font.PLAIN, 12).deriveFont(Font.BOLD, 50));
    		label2.setVerticalAlignment(JLabel.CENTER);
    		label2.setBackground(Color.YELLOW);
    		label2.setOpaque(true);
    		panel.add(label2, gbc);
    		JLabel label3 = new JLabel("testjl"); 
    		label3.setFont(new Font("Arial", Font.ITALIC, 50));
    		label3.setVerticalAlignment(JLabel.CENTER);
    		label3.setBackground(Color.CYAN);
    		label3.setOpaque(true);
    		panel.add(label3, gbc);
     
    		frame.add(panel);
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    		println(1,label1);
    		println(2,label2);
    		println(3,label3);
     
    	}
     
    	private static void println(int i, JLabel label) {
    		System.out.println("Label "+i);
    	 	System.out.println("Dimensions du label : " + label.getWidth()+" × "+ label.getHeight());
    		System.out.println("Position de la ligne de base : "+ label.getBaseline(label.getWidth(), label.getHeight()));
    	}
     
    }


    On voit tout de suite (parce que j'ai coloré le fond, mais tant que ça parce que l'import dans le forum rajoute une espèce de bordure à la c*** - ce sera plus visible lorsque tu exécuteras les programmes ci-joint) que non seulement les dimensions des JLabel sont différentes, mais que le placement dans le composant est différent. On voit également en console que la position de la ligne de base est différente, donc forcément les textes ne sont pas alignés sur la même ligne de base. Mais on voit que non seulement les textes sont centrés dans leur JLabel respectif (en vertical), mais que les JLabel sont centrés dans leur conteneur (ça c'est dû à l'agencement (layout)). Du coup, que les textes soient centrés ensemble seraient du pur hasard.

    Il faudrait déjà qu'ils aient la même ligne de base, ou plutôt que leur ligne de base soient alignées.

    Comme ici :


    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
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.Point;
     
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
     
    public class JFontTest {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JPanel panel = new JPanel(new GridBagLayout()) {
    			protected void paintComponent(java.awt.Graphics g) {
    				super.paintComponent(g);
    				GridBagLayout layout = (GridBagLayout) this.getLayout();
    				Point p = layout.getLayoutOrigin();
    				int[][] ld = layout.getLayoutDimensions(); 
    				int w = 0;
    				int h = ld[1][0];
    				for(int i=0; i<ld[0].length; i++) {
    					w += ld[0][i];
    				}
    				g.setColor(Color.RED);
    				g.fillRect(p.x, p.y, w, h);
     
    			}
    		};
     
    		GridBagConstraints gbc = new GridBagConstraints();
    		gbc.insets = new Insets(5, 5, 5, 5);
    		gbc.anchor = GridBagConstraints.BASELINE;
     
    		JLabel label1 = new JLabel("testjl");
    		label1.setFont(new Font(Font.SERIF, Font.BOLD, 50));
    		label1.setVerticalAlignment(JLabel.CENTER);
    		label1.setBackground(Color.GREEN);
    		label1.setOpaque(true);
    		panel.add(label1, gbc);
    		JLabel label2 = new JLabel("testjl");
    		label2.setFont(new Font("Calibri", Font.PLAIN, 12).deriveFont(Font.BOLD, 50));
    		label2.setVerticalAlignment(JLabel.CENTER);
    		label2.setBackground(Color.YELLOW);
    		label2.setOpaque(true);
    		panel.add(label2, gbc);
    		JLabel label3 = new JLabel("testjl"); 
    		label3.setFont(new Font("Arial", Font.ITALIC, 50));
    		label3.setVerticalAlignment(JLabel.CENTER);
    		label3.setBackground(Color.CYAN);
    		label3.setOpaque(true);
    		panel.add(label3, gbc);
     
    		frame.add(panel);
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    		println(1,label1);
    		println(2,label2);
    		println(3,label3);
     
    	}
     
    	private static void println(int i, JLabel label) {
    		System.out.println("Label "+i);
    	 	System.out.println("Dimensions du label : " + label.getWidth()+" × "+ label.getHeight());
    		System.out.println("Position de la ligne de base : "+ label.getBaseline(label.getWidth(), label.getHeight()));
    	}
     
    }


    Nom : Capture.JPG
Affichages : 224
Taille : 25,1 Ko

    On voit mieux comme ça :
    Nom : Capture.JPG
Affichages : 225
Taille : 22,9 Ko

    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
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.Point;
     
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
     
    public class JFontTest {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JPanel panel = new JPanel(new GridBagLayout()) {
    			protected void paintComponent(java.awt.Graphics g) {
    				super.paintComponent(g);
    				GridBagLayout layout = (GridBagLayout) this.getLayout();
    				Point p = layout.getLayoutOrigin();
    				int[][] ld = layout.getLayoutDimensions(); 
    				int w = 0;
    				int h = ld[1][0];
    				for(int i=0; i<ld[0].length; i++) {
    					w += ld[0][i];
    				}
    				g.setColor(Color.RED);
    				//g.fillRect(p.x, p.y, w, h);
    				g.drawRect(p.x, p.y, w, h);
     
    			}
    		};
     
    		GridBagConstraints gbc = new GridBagConstraints();
    		gbc.insets = new Insets(5, 5, 5, 5);
    		gbc.anchor = GridBagConstraints.BASELINE;
     
    		JLabel label1 = new JLabel("testjl");
    		label1.setFont(new Font(Font.SERIF, Font.BOLD, 50));
    		label1.setVerticalAlignment(JLabel.CENTER);
    //		label1.setBackground(Color.GREEN);
    //		label1.setOpaque(true);
    		panel.add(label1, gbc);
    		JLabel label2 = new JLabel("testjl");
    		label2.setFont(new Font("Calibri", Font.PLAIN, 12).deriveFont(Font.BOLD, 50));
    		label2.setVerticalAlignment(JLabel.CENTER);
    //		label2.setBackground(Color.YELLOW);
    //		label2.setOpaque(true);
    		panel.add(label2, gbc);
    		JLabel label3 = new JLabel("testjl"); 
    		label3.setFont(new Font("Arial", Font.ITALIC, 50));
    		label3.setVerticalAlignment(JLabel.CENTER);
    //		label3.setBackground(Color.CYAN);
    //		label3.setOpaque(true);
    		panel.add(label3, gbc);
     
    		frame.add(panel);
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    		println(1,label1);
    		println(2,label2);
    		println(3,label3);
     
    	}
     
    	private static void println(int i, JLabel label) {
    		System.out.println("Label "+i);
    	 	System.out.println("Dimensions du label : " + label.getWidth()+" × "+ label.getHeight());
    		System.out.println("Position de la ligne de base : "+ label.getBaseline(label.getWidth(), label.getHeight()));
    	}
     
    }


    Les trois mots sont sur la même ligne de base, et le texte qu'il forme est centré verticalement, en tenant compte des métriques (hampes et jambages, en particulier, différents selon les polices).

    En résumé, il faut utiliser un layout manager qui gère des contraintes qui tiennent compte des lignes de bases, comme le GridBagLayout ou le FormLayout de JGoodies (il me semble, je ne suis pas sûr à 100%, ça fait bien 15 ans que je ne m'en suis pas servi).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Par défaut
    Merci pour ta réponse.
    Tu veux dire que le choix du LayoutManager influe sur le positionnement à l'intérieur du JLabel ?

    J'avais contruit un Panel avec un flowLayout par simplicité et parce que j'avais peu d'éléments à afficher. Du coup je vais passer à un gridBagLayout. Je trouvais que c'était compliqué pour rien mais si finalement c'est le seul layoutManager qui me donne un bon rendu alors ça vaut sûrement le coup.

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Vahia Voir le message
    Merci pour ta réponse.
    Tu veux dire que le choix du LayoutManager influe sur le positionnement à l'intérieur du JLabel ?
    Non, mais le LayoutManager influe sur la position du rectangle constitué par la JLabel, et la taille de ce rectangle elle est influencé par le texte dans le JLabel. La taille du JLabel dépend du texte, de façon à l'affiche. Or le texte est placé sur une baseline. Donc la position de la baseline influe sur la partie la plus haute du texte et la partie la plus basse (en fonction des caractères du texte en plus, tout dépend si tu as un caractère avec jambage ou pas, un a, un j, un h et la taille du label n'est pas la même). Donc sur sa taille.

    Citation Envoyé par Vahia Voir le message
    J'avais contruit un Panel avec un flowLayout par simplicité et parce que j'avais peu d'éléments à afficher. Du coup je vais passer à un gridBagLayout. Je trouvais que c'était compliqué pour rien mais si finalement c'est le seul layoutManager qui me donne un bon rendu alors ça vaut sûrement le coup.
    On peut aligner sur la baseline avec un FlowLayout (par défaut, ce n'est pas le cas, les composants sont centrés verticalement, et comme les textes dans les JLabel n'ont pas la même position à l'intérieur, puisque leur taille et leur baseline n'est pas la même, ça fait tout de guingois).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    flowLayout.setAlignOnBaseline(true);
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2015
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2015
    Messages : 185
    Par défaut
    Ok, mais en fait mon problème est partiel car j'ai imposé une taille à mon JLabel qui est bien plus grande que la place occupée par le texte.
    En teintant le fond de mon JLabel, je vois qu'il est parfaitement centré dans son JPanel.

    Mais du coup, puisque l'affichage du JLabel n'est contraint ni en haut, ni en bas car la taille imposée est grande, pourquoi la baseline n'est pas à la même hauteur dans mes 2 codes ?

    Merci pour l'instruction "flowLayout.setAlignOnBaseline(true);". Je n'en ai pas besoin dans mon cas car je n'ai qu'un seul JLabel à afficher mais j'suis content de savoir que ça existe car ça pourra me rendre de grands services à l'avenir.

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Vahia Voir le message
    Ok, mais en fait mon problème est partiel car j'ai imposé une taille à mon JLabel qui est bien plus grande que la place occupée par le texte.
    En teintant le fond de mon JLabel, je vois qu'il est parfaitement centré dans son JPanel.
    Imposer la taille ? Comment ?

    La taille par ailleurs d'influe pas sur le layout du texte dans le label (qui est basé sur la baseline), juste sur le JLabel lui-même. Et l'alignement jour sur les "stringbounds", qui ne dépendent pas de la baseline, mais de la taille de la police.

    Si tu veux vraiment afficher un texte centré dans son composant sans tenir compte de sa baseline, on peut faire un composant dédié :

    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
    176
    177
    178
    179
    public class JText extends JComponent {
     
    	/**
             * 
             */
    	private static final long serialVersionUID = 1L;
     
    	public enum VerticalAlignmentType {
    		BASELINE,
    		FONTHEIGHT,
    		TEXTHEIGHT
    	}
     
    	private String text;
    	private int halign;
    	private int valign;
    	private boolean borderBox;
    	private VerticalAlignmentType vcentermode; 
     
    	public JText() {
    		this("");
    	}
     
    	public JText(String text) {
    		this(text, SwingConstants.CENTER, SwingConstants.CENTER);
    	}
     
    	public JText(String text, int halign, int valign) {
    		this.text=text==null?"":text;
    		this.halign = halign;
    		this.valign = valign;
    		this.borderBox = false;
    		this.vcentermode = VerticalAlignmentType.FONTHEIGHT;
    		setOpaque(false); 
    		setPreferredSize(null);
    	}
     
    	public void setText(String text) {
    		text = text==null?"":text;
    		String oldValue = this.text;
    		this.text = text;
    		if ( !Objects.equals(oldValue, text) ) {
    			firePropertyChange("TEXT", oldValue, text);
    			repaint();
    		}
    	}
     
    	public void setBorderBox(boolean borderBox) {
    		boolean oldValue = this.borderBox;
    		this.borderBox = borderBox;
    		if ( oldValue!=borderBox ) {
    			firePropertyChange("BORDERBOX", oldValue, borderBox);
    			repaint();
    		}
    	}
     
    	public boolean isBorderBox() {
    		return borderBox;
    	} 
     
    	public void setTextVerticalCenterMode(VerticalAlignmentType vcentermode) {
    		VerticalAlignmentType oldValue = this.vcentermode;
    		this.vcentermode = vcentermode==null?VerticalAlignmentType.FONTHEIGHT:vcentermode;
    		if ( oldValue!=vcentermode ) {
    			firePropertyChange("VERTICAL_CENTER_MODE", oldValue, vcentermode);
    			repaint();
    		}
    	}
     
    	public VerticalAlignmentType getTextVerticalCenterMode() {
    		return vcentermode;
    	}
     
    	@Override
    	public Dimension getPreferredSize() {
    		if ( isPreferredSizeSet() ) {
    			return super.getPreferredSize();
    		}
    		else {
    			return computePrefSize();
    		}
    	}
     
    	private Dimension computePrefSize() {
    		Font font = getFont();
    		FontMetrics fontMetrics = getFontMetrics(font);
    		return new Dimension(fontMetrics.stringWidth(text),fontMetrics.getHeight());
    	} 
     
    	@Override
    	public void paint(Graphics g) {
    		super.paint(g); 
     
    		if ( isOpaque() && getBackground()!=null ) {
    			g.setColor(getBackground());
    			g.fillRect(0, 0, getWidth(), getHeight());
    		}
     
    		paintBorder(g);
    		paintComponent(g);
    	}
     
    	@Override
    	protected void paintComponent(Graphics g) {
     
    		super.paintComponent(g);
     
     
    		g.setColor(getForeground());
     
    		Insets insets = getInsets();
    		Rectangle2D bounds;
    		if ( borderBox ) {
    			bounds = new Rectangle2D.Double(insets.left, insets.top, 
    				getWidth()-insets.left-insets.right,
    				getHeight()-insets.top-insets.bottom);
    		}
    		else {
    			bounds = new Rectangle2D.Double(0, 0, 
    					getWidth(),
    					getHeight());
    		}
     
    		Graphics2D g2d = (Graphics2D)g;
     
    		FontMetrics fontMetrics = g.getFontMetrics();
    		Rectangle2D textBounds = fontMetrics.getStringBounds(text, g2d);
     
    		double textWidth = textBounds.getWidth(); 
     
    		double x,y;
     
    		switch (halign) {
    		case SwingConstants.LEFT:
    			x = bounds.getX();
    			break;
    		case SwingConstants.RIGHT:
    			x = bounds.getX() + bounds.getWidth() - textWidth;
    			break;
    		case SwingConstants.CENTER:
    		default:
    			x = bounds.getX()
    			+ (bounds.getWidth() - textWidth) / 2;
    			break;
    		}
     
    		switch (valign) {
    		case SwingConstants.TOP:
    			y = bounds.getY() + fontMetrics.getAscent() - fontMetrics.getDescent();
    			break;
    		case SwingConstants.BOTTOM:
    			y = bounds.getY()
    			+ bounds.getHeight()  - fontMetrics.getDescent() ;
    			break;
    		case SwingConstants.CENTER:
    		default:
    			double height;
    			switch(vcentermode) {
    			case BASELINE:
    				height= fontMetrics.getAscent() + fontMetrics.getDescent();
    				break;
    			case TEXTHEIGHT:
    				height=textBounds.getHeight();
    				break;
    			case FONTHEIGHT:
    			default:
    				height=fontMetrics.getHeight();
    				break;
    			} 
    			y = bounds.getY()
    			+ bounds.getHeight()/ 2  -  height / 2 + fontMetrics.getAscent()  ;
    			break;
    		}	 
     
    		g2d.drawString(text, (int)x, (int)y);
     
    	}
     
    }
    Démo :
    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
    public class Demo {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		FlowLayout flowLayout = new FlowLayout(FlowLayout.CENTER);
    		JPanel panel = new JPanel(flowLayout); 
     
    		JText label = new JText("testjl");
    		label.setFont(new Font("Calibri", Font.PLAIN, 12).deriveFont(Font.BOLD, 50));
    		label.setBackground(Color.YELLOW);
    		label.setOpaque(true);
    		label.setTextVerticalCenterMode(JText.VerticalAlignmentType.TEXTHEIGHT);
    		label.setPreferredSize(new Dimension(300,90));
    		//label.setBorder(BorderFactory.createMatteBorder(10,10,20,10, Color.WHITE));
    		//label.setBorderBox(true);
    		panel.add(label);
     
    		frame.add(panel);
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
     
    	} 
     
    }
    halign et valign permet de sélectionner le type d'alignement horizontal ou vertical
    Le paramètre textVerticalCenterMode permet de choisir comment le centrage vertical se fait :
    • baseline : l'équilibrage (centrage) tient compte de la hauteur de police sans le leading (l'espacement standard prévu entre lignes de texte)
    • hauteur de police : l'équilibrage tient compte que de la hauteur de police (donc ne tient pas compte normalement du texte, mais de la hauteur max, mais là aussi les résultats peuvent dépendre de la police)
    • hauteur de texte : tient compte de la hauteur de texte calculée (dépend également de comment les caractères sont dimensionnés, taille max, taille réelle...)

    Normalement, le baseline fonctionne assez bien, parce que le leading n'est pas inclus, mais avec la police Calibri, c'est pas purement centré, donc il y a quand même un truc de spécial avec cette police. Surtout qu'on dirait que la hauteur de texte est toujours la même quelque soit le texte, c'est-à-dire la hauteur de police. Selon le texte, on a un centrage plus nickel.
    On pourrait ajouter des modes, comme par exemple prendre en compte la hauteur sans juste la moitié de leading (de manière à pas supprimer complètement la séparation entre ligne), ou chercher d'autres moyens de calculer le décalage de la baseline par rapport aux stringbounds. Ou tenter la hauteur de texte moins le leading (pour Calibri ça sert à rien, c'est équivalent à baseline).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. [XSLT]Problème de comportement inattendu
    Par kalimatchoum dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 06/03/2007, 18h33
  2. [Mail] Local / Online => Problème de comportement
    Par MaN@eDeN dans le forum Langage
    Réponses: 22
    Dernier message: 25/12/2006, 11h42
  3. Problème de comportement avec un DBLookUpComboBox ?
    Par bds2006 dans le forum Bases de données
    Réponses: 2
    Dernier message: 17/07/2006, 13h26
  4. [Coldfusion] Problème de comportement des *.cfm
    Par DarkOcean dans le forum Coldfusion
    Réponses: 7
    Dernier message: 21/06/2006, 18h52
  5. [SAX] Problème SAX (comportement de characters)
    Par philmo dans le forum Format d'échange (XML, JSON...)
    Réponses: 4
    Dernier message: 29/09/2005, 11h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo