Home > java > A font chooser combobox for Swing or AWT components

A font chooser combobox for Swing or AWT components

Useful if you want to let the user choose the font to use for certain components of a Swing UI:

package net.doepner.ui.text;

import java.awt.Component;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Arrays;
import java.util.Comparator;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

public class FontChooser extends JComboBox<Font> {

	public FontChooser(final Component... components) {

		final Font[] fonts = GraphicsEnvironment
				.getLocalGraphicsEnvironment()
				.getAllFonts();

		Arrays.sort(fonts, new Comparator<Font>() {
			@Override
			public int compare(Font f1, Font f2) {
				return f1.getName().compareTo(f2.getName());
			}
		});

		for (Font font : fonts) {
			if (font.canDisplayUpTo(font.getName()) == -1) {
				addItem(font);
			}
		}

		addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				final Font font = (Font) e.getItem();
				for (Component comp : components) {
					setFontPreserveSize(comp, font);
				}
			}
		});
		
		setRenderer(new FontCellRenderer());
	}
	
	private static class FontCellRenderer 
			implements ListCellRenderer<Font> {
		
		protected DefaultListCellRenderer renderer = 
				new DefaultListCellRenderer();
		
		public Component getListCellRendererComponent(
				JList<? extends Font> list, Font font, int index, 
				boolean isSelected, boolean cellHasFocus) {
			
			final Component result = renderer.getListCellRendererComponent(
					list, font.getName(), index, isSelected, cellHasFocus);
			
			setFontPreserveSize(result, font);
			return result;
		}
	}

	private static void setFontPreserveSize(final Component comp, Font font) {
		final float size = comp.getFont().getSize();
		comp.setFont(font.deriveFont(size));
	}
}
Advertisements
Categories: java
  1. October 5, 2012 at 13:57

    As the AWT is a bridge to the underlying native user-interface, its implementation on a new operating system may involve a lot of work, especially if it involves any of the AWT GUI widgets, because each of them requires that its native peers be developed from scratch.

    • October 5, 2012 at 17:25

      Hi Stephanie,

      I approved your comment but removed the commercial link. Please keep any future comments free from such links.

      To your point: Swing depends on AWT. Just look at JComponent, for example. It extends java.awt.Component and java.awt.Container and exposes public methods from those classes. Similarly, JFrame and other top-level container classes like JDialog or JWindow extend AWT base classes and expose public methods from them.

      So it is impossible to create a JRE implementation with Swing but without AWT.

      I am not sure if you wanted to imply that Swing is dead because of its dependency on AWT and JavaFX becoming more prominent. Do you think I wasted time blogging about a Swing component? I know JavaFX is all the rage, heavily promoted by Oracle and others and allegedly usable on JSE profiles that do not include Swing/AWT at all.

      I like some ideas in JavaFX, but until JavaFX 2.x is fully open-sourced and matured a little more, I am not abandoning Swing quite yet. :)

      Cheers
      Oliver

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: