# Standard Font-Auswahl-Dialog?



## DEvent (27. Mai 2007)

Hallo,
gibts ein Font-Auswahl-Dialog wie JColorChooser? Würde mir eine menge Arbeit ersparen.

danke, devent.


----------



## JPKI (27. Mai 2007)

Nicht in der Java-Standardbibliothek.


----------



## DEvent (27. Mai 2007)

JPKI hat gesagt.:
			
		

> Nicht in der Java-Standardbibliothek.


hm schade, der JColorChooser ist ziemlich gut. Gibts einen zum freien Download?


----------



## André Uhres (27. Mai 2007)

google einfach nach 'java font chooser'


----------



## JPKI (27. Mai 2007)

Und selbst wenn es da keinen gibt, sowas ist doch schnell geschrieben, nicht wahr?


----------



## DEvent (27. Mai 2007)

JPKI hat gesagt.:
			
		

> Und selbst wenn es da keinen gibt, sowas ist doch schnell geschrieben, nicht wahr?


hab keine Lust das Rad 50 mal neu zu erfinden.


----------



## JPKI (27. Mai 2007)

Tja, so isses eben, das Programmiererleben :wink: !


----------



## JPKI (27. Mai 2007)

Nur so zur Frage: Was soll der Dialog können? Nur Schriftart auswählen oder auch Größe und Stil?


----------



## JPKI (27. Mai 2007)

Ich weiss nicht, was mich geritten hat, aber hier hast du mal einen kleinen, simplen Font-Chooser (hatte grade mal Bock und Zeit):

```
/*
 * @(#) JPKIFontChooser.java
 *
 * Urheberrechtlich geschützt, JPKI.
 * Alle Rechte vorbehalten.
 */

package de.jpki.fontchooser;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * Ein Schriftarten-Auswahldialog.
 *
 * @author JPKI
 * @version 1.00, 27 Mai 2007
 */

public class JPKIFontChooser extends JDialog implements ActionListener {

  private int confirmed;

  private JComboBox fontChooser, styleChooser, sizeChooser;
  private JButton ok, cancel;

  public JPKIFontChooser() {

   this(new JFrame());
 }

  public JPKIFontChooser(JFrame frame) {

   super(frame,"JPKI Schriftarten-Auswahldialog");
   setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

   Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

   setResizable(false);
   setSize(320,240);
   setLocation((dim.width-getSize().width)/2,(dim.height-getSize().height)/2);

   confirmed = 0;

   fontChooser = new JComboBox(createStringArray(GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()));
   fontChooser.setEditable(false);
   fontChooser.setBorder(new TitledBorder("Schriftart"));

   styleChooser = new JComboBox(new String[]{"Standard","Fett","Kursiv"});
   styleChooser.setEditable(false);
   styleChooser.setBorder(new TitledBorder("Schriftstil"));

   sizeChooser = new JComboBox(createIntegerArray(new int[]{8,10,12,14,16,18,20,28,36,72}));
   sizeChooser.setEditable(false);
   sizeChooser.setBorder(new TitledBorder("Schriftgröße"));

   ok = createJButton("Bestätigen","ok");
   cancel = createJButton("Abbrechen","cancel");

   JPanel comboPanel = new JPanel(new GridLayout(3,1));
   comboPanel.add(fontChooser);
   comboPanel.add(styleChooser);
   comboPanel.add(sizeChooser);

   JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,10));
   buttonPanel.add(ok);
   buttonPanel.add(cancel);   

   getContentPane().setLayout(new BorderLayout());
   getContentPane().add(comboPanel,BorderLayout.CENTER);
   getContentPane().add(buttonPanel,BorderLayout.SOUTH);
 }

  public Font showFontDialog() {

    setVisible(true);

    while (confirmed == 0)
     try { Thread.sleep(40); } catch (InterruptedException ex) {}

    if (confirmed == 2) {

     dispose();
     confirmed = 0;
     return null;
  }

    int style, size;
    String selectedStyle = (String)styleChooser.getSelectedItem();

    size = ((Integer)sizeChooser.getSelectedItem()).intValue();

    if (selectedStyle.equals("Standard"))
     style = Font.PLAIN;
    else if (selectedStyle.equals("Fett"))
     style = Font.BOLD;
    else
     style = Font.ITALIC;

    dispose();
    confirmed = 0;
    return new Font((String)fontChooser.getSelectedItem(),style,size);
 }

  public void actionPerformed(ActionEvent e) {

   String aC = e.getActionCommand();

   if (aC.equals("ok"))
    confirmed = 1;
   else
    confirmed = 2;
 }

  private Integer[] createIntegerArray(int numbers[]) {

   Integer integer[] = new Integer[numbers.length];

   for (int i = 0; i < numbers.length; i++)
    integer[i] = new Integer(numbers[i]);

   return integer;
 }

  private String[] createStringArray(Font fonts[]) {

   String string[] = new String[fonts.length];

   for (int i = 0; i < fonts.length; i++)
    string[i] = fonts[i].getName();

   return string;
 }

  private JButton createJButton(String title, String actionCommand) {

   JButton button = new JButton(title);
   button.setActionCommand(actionCommand);
   button.addActionListener(this);

   return button;
 }
}
```

Edit: Das ganze hat mit Schreiben im Editor und Testen nur 10 Minuten gedauert...


----------



## DEvent (27. Mai 2007)

danke für die Mühe, aber ich dachte da eher an einen normalen Fontauswahl-Dialog, wie man ihn von so vielen Windows/KDE/Gnome Anwendungen kennt, die etwas mit Textverarbeitung zu tun haben. Also sollte schon mit Vorschau usw. sein.

Ausserdem, machst du das immer so bei Dialogen:

```
setVisible(true);
     while (confirmed == 0) 
     try { Thread.sleep(40); } catch (InterruptedException ex) {} 

    if (confirmed == 2) { 

     dispose(); 
     confirmed = 0; 
     return null; 
  }
```
Ein einfaches setModal(true) reicht da eigentlich. Denn mit der While-Schleife hast du den gesammten GUI-Thread blockiert, was meine Programm-Einfrierung erklären würde.


----------



## JPKI (27. Mai 2007)

Ja, aber mit setModal() hätte ich das Problem nicht lösen können.
Dann wäre ja actionPerformed() ausgeführt worden, das hat ja den Typ void, und ich wollte doch ein Font-Objekt zurückgeben.
Was die Vorschau angeht: Du kannst den Quelltext doch nach deinen  Vorlieben ändern.

Edit: Das hier ist mein 500ster Beitrag. Mann, bin ich stolz :wink:


----------



## DEvent (28. Mai 2007)

Also entweder bin ich zu blöd, oder???
Wieso funktioniert JCheckBox#isSelected() nicht mehr?

Wieso liefert mir JCheckBox#isSelected() immer false???


```
/*
 * Copyright (c) Ian F. Darwin, [url]http://www.darwinsys.com/[/url], 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 * A font selection dialog.
 * 


 * Note: can take a long time to start up on systems with (literally) hundreds
 * of fonts.
 * 
 * @author Ian Darwin
 * @version $Id: FontChooser.java,v 1.19 2004/03/20 20:44:56 ian Exp $
 */
public class FontChooser extends JDialog
{
    /**
     * 
     */
    private static final long serialVersionUID = -8257358275295265984L;

    /** The font the user has chosen */
    protected Font resultFont;

    /** Display text */
    protected String displayText = "Qwerty Yuiop";

    /** The list of Fonts */
    protected String fontList[];

    /** The font name chooser */
    protected JList fontNameChoice;

    /** The font size chooser */
    protected JList fontSizeChoice;

    /** The bold and italic choosers */
    private JCheckBox bold, italic;

    /** The list of font sizes */
    protected Integer fontSizes[] =
    { 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 30, 36,
            40, 48, 60, 72 };

    /** The index of the default size (e.g., 14 point == 4) */
    protected static final Integer DEFAULT_SIZE = 4;

    /**
     * The display area. Use a JLabel as the AWT label doesn't always honor
     * setFont() in a timely fashion :-)
     */
    protected JLabel previewArea;

    private final Font oldfont;

    private JButton okButton;

    private JButton canButton;

    /**
     * Construct a FontChooser -- Sets title and gets array of fonts on the
     * system. Builds a GUI to let the user choose one font at one size.
     */
    public FontChooser(Frame f, Font oldfont_)
    {
        super(f, "Font Chooser", true);

        this.oldfont = oldfont_;

        setLayout(new BorderLayout());

        previewArea = new JLabel(displayText, JLabel.CENTER);
        previewArea.setSize(200, 50);

        add(createTop(), BorderLayout.NORTH);
        add(previewArea, BorderLayout.CENTER);
        add(createBottom(), BorderLayout.SOUTH);

        setupDialog();
        previewFont(); // ensure view is up to date!

        pack();
        setLocation(100, 100);
    }

    private Component createBottom()
    {
        JPanel bot = new JPanel();

        okButton = new JButton("Apply");
        okButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                previewFont();
                setVisible(false);
            }
        });

        canButton = new JButton("Cancel");
        canButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                // Set all values to null. Better: restore previous.
                resultFont = oldfont;
                setVisible(false);
            }
        });

        bot.add(okButton);
        bot.add(canButton);

        return bot;
    }

    private Component createTop()
    {
        JPanel top = new JPanel(new FlowLayout());

        // Toolkit toolkit = Toolkit.getDefaultToolkit();
        // For JDK 1.1: returns about 10 names (Serif, SansSerif, etc.)
        // fontList = toolkit.getFontList();
        // For JDK 1.2: a much longer list; most of the names that come
        // with your OS (e.g., Arial), plus the Sun/Java ones (Lucida,
        // Lucida Bright, Lucida Sans...)
        fontList = GraphicsEnvironment.getLocalGraphicsEnvironment()
                .getAvailableFontFamilyNames();

        fontNameChoice = new JList(fontList);
        fontNameChoice.setSelectedIndex(0);
        fontNameChoice.addListSelectionListener(new ListSelectionListener()
        {
            @Override
            public void valueChanged(ListSelectionEvent e)
            {
                previewFont();
            }
        });

        fontSizeChoice = new JList(fontSizes);
        fontSizeChoice.setSelectedValue(DEFAULT_SIZE, true);
        fontSizeChoice.addListSelectionListener(new ListSelectionListener()
        {
            @Override
            public void valueChanged(ListSelectionEvent e)
            {
                previewFont();
            }
        });

        top.add(new JScrollPane(fontNameChoice), "0, 0");
        top.add(new JScrollPane(fontSizeChoice), "1, 0");
        top.add(createAttributes(), "2, 0");
        createAttributes();

        return top;
    }

    private Component createAttributes()
    {
        JPanel attrs = new JPanel(new GridLayout(0, 1));

        bold = new JCheckBox("Bold");
        bold.addItemListener(new ItemListener()
        {
            @Override
            public void itemStateChanged(ItemEvent e)
            {
                previewFont();
            }
        });

        italic = new JCheckBox("Italic");
        italic.addItemListener(new ItemListener()
        {
            @Override
            public void itemStateChanged(ItemEvent e)
            {
                previewFont();
            }
        });

        attrs.add(bold);
        attrs.add(italic);

        return attrs;
    }

    private void setupDialog()
    {
        if ( oldfont != null )
        {
            fontNameChoice.setSelectedValue(oldfont.getName(), true);
            fontSizeChoice.setSelectedValue(oldfont.getSize(), true);
            bold.setSelected(oldfont.isBold());
            italic.setSelected(oldfont.isItalic());
        }
    }

    /**
     * Called from the action handlers to get the font info, build a font, and
     * set it.
     */
    protected void previewFont()
    {
        String resultName = (String) fontNameChoice.getSelectedValue();
        Object selectedsize = fontSizeChoice.getSelectedValue();
        int resultSize = DEFAULT_SIZE;
        if ( selectedsize != null )
        {
            resultSize = (Integer) selectedsize;
        }

        boolean isBold = bold.isSelected();
        boolean isItalic = italic.isSelected();
        int attrs = Font.PLAIN;

        System.out.println("Preview");
        System.out.println("Bold: " + bold.isSelected());
        System.out.println("Italic: " + italic.isSelected());

        if ( isBold ) attrs = Font.BOLD;
        if ( isItalic ) attrs |= Font.ITALIC;
        resultFont = new Font(resultName, attrs, resultSize);
        // System.out.println("resultName = " + resultName + "; " +
        // "resultFont = " + resultFont);
        previewArea.setFont(resultFont);
        pack(); // ensure Dialog is big enough.
    }

    /** Retrieve the selected font, or null */
    public Font getSelectedFont()
    {
        return resultFont;
    }

    /** Simple main program to start it running */
    public static void main(String[] args)
    {
        final JFrame f = new JFrame("FontChooser Startup");
        final FontChooser fc = new FontChooser(f, null);
        final Container cp = f.getContentPane();
        cp.setLayout(new GridLayout(0, 1)); // one vertical column

        JButton theButton = new JButton("Change font");
        cp.add(theButton);

        final JLabel theLabel = new JLabel("Java is great!", JLabel.CENTER);
        cp.add(theLabel);

        // Now that theButton and theLabel are ready, make the action listener
        theButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                fc.setVisible(true);
                Font myNewFont = fc.getSelectedFont();
                System.out.println("You chose " + myNewFont);
                theLabel.setFont(myNewFont);
                f.pack(); // adjust for new size
                fc.dispose();
            }
        });

        f.setSize(200, 200);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
```

btw, JCheckBox#setSelected() funktioniert auch nicht???
Immer das gleiche wenn man fremden Code benutzt, irgendwas geht immer schief  :x


----------



## DEvent (28. Mai 2007)

JPKI hat gesagt.:
			
		

> Ja, aber mit setModal() hätte ich das Problem nicht lösen können.
> Dann wäre ja actionPerformed() ausgeführt worden, das hat ja den Typ void, und ich wollte doch ein Font-Objekt zurückgeben.
> Was die Vorschau angeht: Du kannst den Quelltext doch nach deinen  Vorlieben ändern.
> 
> Edit: Das hier ist mein 500ster Beitrag. Mann, bin ich stolz :wink:


Dafür frierst du aber den GUI-Thread ein, so das man garnichts mehr benutzen kann.


```
Font getSelectedFont()
{
    setModal(true);
    setVisible(true); // Der Code wird solange angehalten,
                                  // bis der Benutzer das Dialog schließt
                                  // ohne den GUI-Thread zu stoppen
    if ( confirmed )
    {
         return neuer_font;
    }
    else return alter_font;
```


----------



## kleiner_held (28. Mai 2007)

createAttributes();  wird ein zweites mal aufgerufen (Zeile 210) damit werden die JCheckBox Instanzen überschrieben.


----------



## André Uhres (28. Mai 2007)




----------



## DEvent (28. Mai 2007)

kleiner_held hat gesagt.:
			
		

> createAttributes();  wird ein zweites mal aufgerufen (Zeile 210) damit werden die JCheckBox Instanzen überschrieben.


Danke  das habe ich total übersehen, jetzt funktioniert der Dialog.


----------

