[utilitaire] dialogue de sélection de police : fontchooser (jfilechooser et jcolorchooser like)

Description

Voici un petit module que j'avais programmé à l'occasion d'un projet.
C'est une classe qui permet d'afficher un dialogue de sélection de police (comme les dialogues traditionnels, avec une liste des polices disponibles, la taille, le style comme gras, italique, etc... et un cadre qui donne un aperçu avec la chaîne AaBbCc...)

Elle fonctionne comme JFileChooser (ou JColorChooser), c'est à dire que l'on initialise une instance en passant en paramètre le titre du dialogue (facultatif, "Sélectionnez une police" par défaut) et la police sélectionnée par défaut (facultatif aussi, mis à "Courier New" par défaut).
On apelle ensuite la méthode showDialog(), qui ne retourne que lorsque l'utilisateur a validé ou fermé la fenêtre.

enfin, on récupère la police choisie grâce à la méthode getSelectedFont(), qui peut renvoyer null si la boîte de dialogue a été fermée.
Pour savoir si c'est le cas, on récupérer la valeur renvoyée par showDialog(), qui peut être FontChooser.OK ou FontChooser.CANCELED

On peut modifier le titre du dialogue grâce à setTitle(String titre), et sa position à l'écran via setLocation(int x, int y).

a++, et bonne prog !

Source / Exemple :


/*

  • @(#)FontChooser.java 1.0 08/08/04
*
  • /
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; /**
  • FontChooser est une classe permettant d'afficher une boîte de dialogue de selection de police.
  • Il fonctionne un peu comme <code>JColorChooser
ou
JFileChooser
.
  • <P>
  • Il permet la séléction:
  • <ul>
  • <li>De la police. Il affiche toutes les polices obtenues grace à la méthode
    getAllFont()
  • de la classe
    java.awt.GraphicsEnvironment
    . Il affiche la police courante dans le
    JTextField
    apercu.
  • <li>Du style. Une
    JList
    permet la séléction du style "Standard" (plain),"Gras" (bold) ou "Italique"(italic).
  • <li>De la taille. On peut choisir dans une
    JList
    ou l'entrer nous même.
  • </ul>

  • *
    • @author lovejava(Yann Hamdaoui)
    • @version 1.0 08/08/04
    • @since 1.4
    • /


    public class FontChooser extends Object
    {
    /**
    • Permet la récupération de touts les polices installées
    • /

    protected GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    /**
    • Contraintes relatives à l'affichage
    • /

    protected GridBagConstraints contraintes = new GridBagConstraints();
    /**
    • Police de départ spécifiée dans le constructeur (par défaut la police "Courier")
    • /

    protected Font policeDepart;
    /**
    • Police en cours utilisé pour la methode
      getFont()
      et pour l'affichage dans l'aperçu
    • /

    protected Font policeEnCours;
    /**
    • boîte de dialogue utilisé pour l'affichage
    • /

    protected JDialog dialogue = new JDialog();
    /**
    • Indique que l'utilisateur a cliqué sur OK
    • /

    public static final int OK = 0;
    /**
    • Indique que l'utilisateur a cliqué sur annuler ou a fermé la fenêtre
    • /

    public static final int CANCELED = 1;
    /**
    • Zone de texte utilisée pour l'aperçu de la police en cours
    • /

    protected JTextField apercu;
    /**
    • JList
      utilisée pour les polices
    • /

    protected JList listePolice;
    /**
    • JList
      utilisée pour le style
    • /

    protected JList listeStyle;
    /**
    • JList
      utilisée pour la taille
    • /

    protected JList listeTaille;

    /**
    • Etat retourné par showDialog() (
      FontChooser.OK
      ou
      FontChooser.CANCELED
      );
    • /

    protected int etat = -1;

    /**
    • Méthode utilisée pour faciliter l'ajout de composant avec
      GridBagLayout
    • @param conteneur Conteneur où ajouter le composant
    • @param composant Le composant à ajouter
    • @param x La colonne dans laquelle ajouter le composant
    • @param y La ligne dans laquelle ajouter le composant
    • /

    protected void addGB(Container conteneur, Component composant, int x, int y)
    {
    contraintes.gridx = x; contraintes.gridy = y;
    conteneur.add(composant, contraintes);
    }

    /**
    • Retourne la police séléctionné lors du derniers appel à
      showDialog()
    • renvoi
      null
      si cette méthode n'a jamais été appelée ou si elle a renvoyé
      CANCELED
    • @return La police séléctionée ou null si etat vaut
      CANCELED
    • ou si la méthode
      showDialog()
      n'a jamais été appelée
    • /

    public Font getSelectedFont()
    {
    if(etat == -1 || etat == FontChooser.CANCELED)
    return null;
    else
    return policeEnCours;
    }

    /**
    • Modifie le titre de la boîte de dialogue
    • @param titre Le nouveau titre de la boîte de dialogue
    • /

    public void setTitle(String titre)
    {
    dialogue.setTitle(titre);
    }

    /**
    • Modifie la position de la boîte de dialogue
    • @param a La valeur de x pour la nouvelle position
    • @param b La valeur de y pour la nouvelle position
    • /

    public void setLocation(int a, int b)
    {
    dialogue.setLocation(a,b);
    }

    /**
    • Construit une boîte de dialogue avec la police f par défaut et avec le titre spécifié
    • @param titre Le titre de la boîte de dialogue
    • @param f La police par défaut
    • /

    public FontChooser(String titre, Font f)
    {
    policeDepart = f;
    dialogue.setTitle(titre);
    }

    /**
    • Construit une boîte de dialogue avec la police "Courier New" et le titre "Sélectionnez une police"
    • /

    public FontChooser()
    {
    this("Sélectionnez une police", new Font("Courier New", Font.PLAIN, 12));
    }

    /**
    • Construit une boîte de dialogue avec la police f par défaut et le titre "Sélectionnez une police"
    • @param f La police par défaut
    • /

    public FontChooser(Font f)
    {
    this("Sélectionnez une police", f);
    }

    /**
    • Construit une boîte de dialogue avec la police "Courier New" et le titre spécifié
    • @param titre Le titre de la boîte de dialogue
    • /

    public FontChooser(String titre)
    {
    this(titre, new Font("Courier New", Font.PLAIN, 12));
    }

    /**
    • Affiche la boîte de dialogue. Attend jusqu'a la fermeture et renvoi
      OK
      ou
      CANCELED
    • @return Retourne soit:<br>
    • OK
      si l'utilisateur clique sur OK<br>
    • CANCELED
      si l'utilisateur clique sur annuler ou ferme la boîte de dialogue
    • /

    public int showDialog()
    {
    policeEnCours = policeDepart.deriveFont(policeDepart.getStyle());

    Container conteneur = dialogue.getContentPane();
    conteneur.setLayout(new GridBagLayout());

    JTextField police = new JTextField();
    JTextField style = new JTextField();
    JFormattedTextField taille = new JFormattedTextField();
    taille.addKeyListener(new TailleInputAdapter());
    apercu = new JTextField();

    listePolice = new JList(ge.getAvailableFontFamilyNames());
    listeStyle = new JList(new String[]{"Standard","Gras","Italique"});
    listeTaille = new JList(new Integer[]{new Integer(8),new Integer(9),new Integer(10),new Integer(11),new Integer(12),new Integer(14),new Integer(16),new Integer(18),new Integer(20),new Integer(22),new Integer(24),new Integer(26),new Integer(28),new Integer(36),new Integer(48),new Integer(72)});

    JButton boutonOk = new JButton("Ok");
    JButton boutonAnnuler = new JButton("Annuler");

    police.setText(obtenirPolice(policeDepart));
    style.setText(obtenirStyle(policeDepart.getStyle()));
    taille.setValue(new Integer(obtenirTaille(policeDepart.getSize())));
    apercu.setText("AaBbCcDdWwXxYyZz");
    apercu.setFont(policeEnCours);

    TitledBorder bordureApercu = new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED));
    TitledBorder bordurePolice = new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED));
    TitledBorder bordureStyle = new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED));
    TitledBorder bordureTaille = new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED));

    bordureApercu.setTitle("Aperçu");
    bordurePolice.setTitle("Police");
    bordureStyle.setTitle("Style");
    bordureTaille.setTitle("Taille");

    apercu.setBorder(bordureApercu);

    police.setEnabled(false);
    style.setEnabled(false);

    listePolice.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    listeStyle.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    listeTaille.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    listePolice.addListSelectionListener(new ListePoliceAdapter(police));
    listeStyle.addListSelectionListener(new ListeStyleAdapter(style));
    listeTaille.addListSelectionListener(new ListeTailleAdapter(taille));

    boutonOk.addActionListener(new BoutonOkAdapter());
    boutonAnnuler.addActionListener(new BoutonAnnulerAdapter());

    contraintes.fill = GridBagConstraints.BOTH;

    JPanel panelPolice,panelStyle,panelTaille,panelCommandes;

    panelPolice = new JPanel();
    panelStyle = new JPanel();
    panelTaille = new JPanel();

    panelPolice.setLayout(new GridBagLayout());
    panelStyle.setLayout(new GridBagLayout());
    panelTaille.setLayout(new GridBagLayout());

    panelPolice.setBorder(bordurePolice);
    panelStyle.setBorder(bordureStyle);
    panelTaille.setBorder(bordureTaille);

    contraintes.gridheight = 1;

    addGB(panelPolice,police,0,0);
    addGB(panelStyle,style,0,0);
    addGB(panelTaille,taille,0,0);

    contraintes.gridheight = 3;

    addGB(panelPolice,new JScrollPane(listePolice),0,1);
    addGB(panelStyle,listeStyle,0,1);
    addGB(panelTaille,new JScrollPane(listeTaille),0,1);

    panelCommandes = new JPanel();
    panelCommandes.add(boutonOk);
    panelCommandes.add(boutonAnnuler);

    addGB(conteneur,panelPolice,0,0);
    addGB(conteneur,panelStyle,1,0);
    addGB(conteneur,panelTaille,2,0);

    contraintes.gridheight = 1;

    addGB(conteneur,apercu,1,3);
    addGB(conteneur,panelCommandes,1,4);

    dialogue.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
    dialogue.setSize(600,450);
    dialogue.addWindowListener(new DialogueAdapter());
    dialogue.setVisible(true);

    while(dialogue.isVisible()) Thread.yield();
    return etat;
    }

    /**
    • Méthode interne permettant des manipulations sur la liste
      listePolice
    • @param f La police de départ
    • @return Le résultat de la méthode
      getName()
      de l'objet f
    • /

    protected String obtenirPolice(Font f)
    {
    listePolice.setSelectedValue(f.getName(),true);
    return f.getName();
    }

    /**
    • Méthode interne permettant des manipulations sur la liste
      listeStyle
    • @param style Le style à convertir sous forme d'int (
      Font.BOLD
      par exemple)
    • @return Un style sous forme de chaine ("Gras" par exemple)
    • /

    protected String obtenirStyle(int style)
    {
    switch(style)
    {
    case Font.PLAIN: listeStyle.setSelectedValue("Standard",true);
    return "Standard";
    case Font.BOLD: listeStyle.setSelectedValue("Gras",true);
    return "Gras";
    case Font.ITALIC: listeStyle.setSelectedValue("Italique",true);
    return "Italique";
    default: return obtenirStyle(Font.PLAIN);
    }
    }

    /**
    • Méthode interne permettant des manipulations sur la liste
      listeTaille
    • @param taille La taille sous forme d'int
    • @return La taille sous forme de chaine grâce à la méthode
      valueOf()
      de la classe
      java.lang.String
    • /

    protected String obtenirTaille(int taille)
    {
    listeTaille.setSelectedValue(new Integer(taille),true);
    return String.valueOf(taille);
    }

    /**
    • classe permettant de gérer les
      ListSelectionListener
      en provenance de
      listePolice
    • /

    protected class ListePoliceAdapter implements ListSelectionListener
    {
    /**
    • Champ à modifier si un changement viens
    • /

    private JTextField champ;


    /**
    • constructeur avec le
      JTextField
      spécifié
    • @param jtf Le champ à modifier
    • /

    ListePoliceAdapter(JTextField jtf)
    {
    champ = jtf;
    }

    /**
    • Si la sélection change on modifie le champ et la police et on met à jour l'aperçu
    • /

    public void valueChanged(ListSelectionEvent lse)
    {
    if(listePolice.getSelectedValue() == null) return;
    champ.setText(listePolice.getSelectedValue().toString());
    policeEnCours = new Font(champ.getText(), policeEnCours.getStyle(), policeEnCours.getSize());
    apercu.setFont(policeEnCours);
    }
    }

    /**
    • classe permettant de gérer les
      ListSelectionListener
      en provenance de
      listeStyle
    • /

    protected class ListeStyleAdapter implements ListSelectionListener
    {
    /**
    • Champ à modifier si un changement viens
    • /

    private JTextField champ;


    /**
    • constructeur avec le
      JTextField
      spécifié
    • @param jtf Le champ à modifier
    • /

    ListeStyleAdapter(JTextField jtf)
    {
    champ = jtf;
    }

    /**
    • Si la sélection change on modifie le champ et la police et on met à jour l'aperçu
    • /

    public void valueChanged(ListSelectionEvent lse)
    {
    if(listeStyle.getSelectedValue() == null) return;
    champ.setText(listeStyle.getSelectedValue().toString());
    policeEnCours = policeEnCours.deriveFont(styleStrToInt(champ.getText()));
    apercu.setFont(policeEnCours);
    }

    /**
    • Méthode interne permettant de convertir une chaine en int par exemple:
    • "Standard" sera convertit en Font.PLAIN
    • "Gras" sera convertit en Font.BOLD
    • @param style La chaine à convertir
    • @return Le champ de Font correspondant
    • /

    private int styleStrToInt(String style)
    {
    if(style.equals("Standard")) return Font.PLAIN;
    if(style.equals("Italique")) return Font.ITALIC;
    if(style.equals("Gras")) return Font.BOLD;
    return styleStrToInt("Standard");
    }
    }

    /**
    • classe permettant de gérer les
      ListSelectionListener
      en provenance de
      listeTaille
    • /

    protected class ListeTailleAdapter implements ListSelectionListener
    {
    /**
    • Champ à modifier si un changement viens
    • /

    private JTextField champ;

    /**
    • constructeur avec le
      JTextField
      spécifié
    • @param jtf Le champ à modifier
    • /

    ListeTailleAdapter(JTextField jtf)
    {
    champ = jtf;
    }

    /**
    • Si la sélection change on modifie le champ et la police et on met à jour l'aperçu
    • /

    public void valueChanged(ListSelectionEvent lse)
    {
    if(listeTaille.getSelectedValue() == null) return;
    champ.setText(listeTaille.getSelectedValue().toString());
    policeEnCours = policeEnCours.deriveFont( (float) ((Integer)listeTaille.getSelectedValue()).intValue());
    apercu.setFont(policeEnCours);
    }
    }

    /**
    • classe permettant de gérer les
      ActionListener
      en provenance du boutont ok
    • /

    protected class BoutonOkAdapter implements ActionListener
    {
    /**
    • Ferme la boîte de dialogue et renvoi
      OK
    • /

    public void actionPerformed(ActionEvent ae)
    {
    etat = FontChooser.OK;
    dialogue.setVisible(false);
    }
    }


    /**
    • classe permettant de gérer les
      ActionListener
      en provenance du boutont annuler
    • /

    protected class BoutonAnnulerAdapter implements ActionListener
    {
    /**
    • Ferme la boîte de dialogue et renvoi
      CANCELED
    • /

    public void actionPerformed(ActionEvent ae)
    {
    etat = FontChooser.CANCELED;
    dialogue.setVisible(false);
    }
    }

    /**
    • classe gérant les entrées numériques dans le champ taille
    • /

    protected class TailleInputAdapter extends KeyAdapter
    {
    /**
    • Quand on presse une touche on modifie la taille de la police en conséquant
    • /

    public void keyTyped(KeyEvent ke)
    {
    JFormattedTextField jtf = (JFormattedTextField)ke.getSource();
    char caract = ke.getKeyChar();
    String toucheCourante = "";
    if(Character.isDigit(caract)) toucheCourante = String.valueOf(caract);
    try {policeEnCours = policeEnCours.deriveFont( (float)Integer.parseInt(jtf.getText() + toucheCourante) ); }
    catch(Exception e)
    {
    JOptionPane.showMessageDialog(dialogue,"Vous ne devez saisir que des nombres entiers dans ce champ","Erreur",JOptionPane.WARNING_MESSAGE);
    jtf.setValue(new Integer(policeEnCours.getSize()));
    return;
    }
    listeTaille.setSelectedValue(new Integer(policeEnCours.getSize()),true);
    apercu.setFont(policeEnCours);
    }
    }

    /**
    • Classe gérant les évènement en provenance de
      dialogue
    • /

    protected class DialogueAdapter extends WindowAdapter
    {
    /**
    • Si la fenêtre est fermée, on met la valeur d'état à
      CANCELED
    • /

    public void windowClosing(WindowEvent we)
    {
    etat = FontChooser.CANCELED;
    dialogue.setVisible(false);
    }
    }

    /**
    • Possède une méthode
      main
      qui permet de l'éxecuter à des fins de test et de débogage
    • @param args Les arguments passés au programme lors de l'éxecution
    • /

    public static void main(String args[])
    {
    FontChooser fc = new FontChooser();
    System.out.println(fc);
    fc.setLocation(250,250);
    int resultat = fc.showDialog();
    Font resultat2 = fc.getSelectedFont();
    System.out.println("Retour de showDialog(): " + resultat);
    System.out.println("Police sélectionnée: " + resultat2);
    System.out.println(fc);
    System.exit(0);
    }

    /**
    • Une représentation du FontChooser sous forme de chaîne
    • @return Une représentation de l'objet FontChooser sous forme de chaîne
    • /

    public String toString()
    {
    String etatStr = "";
    switch(etat)
    {
    case OK: etatStr = "OK";
    break;
    case CANCELED: etatStr = "CANCELED";
    break;
    default: etatStr = "NONE";
    break;
    }
    if(policeEnCours == null) policeEnCours = policeDepart;
    return "FontChooser[font=" + policeEnCours.getName() + ";defaultfont=" + policeDepart.getName() + ";state=" + etatStr + "]";
    }
    }
    </code>

    Conclusion :


    pas de futures version prévues, sauf demandes éventuelles. En survolant le code, je pense que la boucle while(dialogue.isVisible()) pourraît peut être tirer partie du wait()/notify()...à voir

    Codes Sources

    A voir également

    Vous n'êtes pas encore membre ?

    inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

    Les membres obtiennent plus de réponses que les utilisateurs anonymes.

    Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

    Le fait d'être membre vous permet d'avoir des options supplémentaires.