现在的位置: 首页 > 综合 > 正文

Java Swing写的字体选择器,仿记事本中的字体控件

2017年11月29日 ⁄ 综合 ⁄ 共 12228字 ⁄ 字号 评论关闭

Java Swing 写的字体选择器,仿记事本中的字体控件,使用操作方法与文件选择器JFileChooser基本相同。

 

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
 * 字体选择器,仿记事本中的字体控件,使用操作方法与文件选择器JFileChooser基本相同。
 * @author 米强<转载请注明作者与来源>
 * @blog http://blog.csdn.net/mq612
 * @blog http://hi.baidu.com/mq612/blog
 *
 */
@SuppressWarnings("serial")
public class MQFontChooser extends JDialog {
	/**
	 * 选择取消按钮的返回值
	 */
	public static final int CANCEL_OPTION = 0;
	/**
	 * 选择确定按钮的返回值
	 */
	public static final int APPROVE_OPTION = 1;
	/**
	 * 中文预览的字符串
	 */
	private static final String CHINA_STRING = "神马都是浮云!";
	/**
	 * 英文预览的字符串
	 */
	private static final String ENGLISH_STRING = "Hello Kitty!";
	/**
	 * 数字预览的字符串
	 */
	private static final String NUMBER_STRING = "0123456789";
	// 预设字体,也是将来要返回的字体
	private Font font = null;
	// 字体选择器组件容器
	private Box box = null;
	// 字体文本框
	private JTextField fontText = null;
	// 样式文本框
	private JTextField styleText = null;
	// 文字大小文本框
	private JTextField sizeText = null;
	// 预览文本框
	private JTextField previewText = null;
	// 中文预览
	private JRadioButton chinaButton = null;
	// 英文预览
	private JRadioButton englishButton = null;
	// 数字预览
	private JRadioButton numberButton = null;
	// 字体选择框
	private JList fontList = null;
	// 样式选择器
	private JList styleList = null;
	// 文字大小选择器
	private JList sizeList = null;
	// 确定按钮
	private JButton approveButton = null;
	// 取消按钮
	private JButton cancelButton = null;
	// 所有字体
	private String [] fontArray = null;
	// 所有样式
	private String [] styleArray = {"常规", "粗体", "斜体", "粗斜体"};
	// 所有预设字体大小
	private String [] sizeArray = {"8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48", "初号", "小初", "一号", "小一", "二号", "小二", "三号", "小三", "四号", "小四", "五号", "小五", "六号", "小六", "七号", "八号"};
	// 上面数组中对应的字体大小
	private int [] sizeIntArray = {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 42, 36, 26, 24, 22, 18, 16, 15, 14, 12, 10, 9, 8, 7, 6, 5};
	// 返回的数值,默认取消
	private int returnValue = CANCEL_OPTION;
	/**
	 * 体构造一个字体选择器
	 */
	public MQFontChooser() {
		this(new Font("宋体", Font.PLAIN, 12));
	}
	/**
	 * 使用给定的预设字体构造一个字体选择器
	 * @param font 字体
	 */
	public MQFontChooser(Font font) {
		setTitle("字体选择器");
		this.font = font;
		// 初始化UI组件
		init();
		// 添加监听器
		addListener();
		// 按照预设字体显示
		setup();
		// 基本设置
		setModal(true);
		setResizable(false);
		// 自适应大小
		pack();
	}
	/**
	 * 初始化组件
	 */
	private void init(){
		// 获得系统字体
		GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment();
		fontArray = eq.getAvailableFontFamilyNames();
		// 主容器
		box = Box.createVerticalBox();
		box.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
		fontText = new JTextField();
		fontText.setEditable(false);
		fontText.setBackground(Color.WHITE);
		styleText = new JTextField();
		styleText.setEditable(false);
		styleText.setBackground(Color.WHITE);
		sizeText = new JTextField("12");
		// 给文字大小文本框使用的Document文档,制定了一些输入字符的规则
		Document doc = new PlainDocument(){
			public void insertString(int offs, String str, AttributeSet a)
					throws BadLocationException {
				if (str == null) {
					return;
				}
				if (getLength() >= 3) {
					return;
				}
				if (!str.matches("[0-9]+") && !str.equals("初号") && !str.equals("小初") && !str.equals("一号") && !str.equals("小一") && !str.equals("二号") && !str.equals("小二") && !str.equals("三号") && !str.equals("小三") && !str.equals("四号") && !str.equals("小四") && !str.equals("五号") && !str.equals("小五") && !str.equals("六号") && !str.equals("小六") && !str.equals("七号") && !str.equals("八号")) {
					return;
				}
				super.insertString(offs, str, a);
				sizeList.setSelectedValue(sizeText.getText(), true);
			}
		};
		sizeText.setDocument(doc);
		previewText = new JTextField(20);
		previewText.setHorizontalAlignment(JTextField.CENTER);
		previewText.setEditable(false);
		previewText.setBackground(Color.WHITE);
		chinaButton = new JRadioButton("中文预览", true);
		englishButton = new JRadioButton("英文预览");
		numberButton = new JRadioButton("数字预览");
		ButtonGroup bg = new ButtonGroup();
		bg.add(chinaButton);
		bg.add(englishButton);
		bg.add(numberButton);
		fontList = new JList(fontArray);
		styleList = new JList(styleArray);
		sizeList = new JList(sizeArray);
		approveButton = new JButton("确定");
		cancelButton = new JButton("取消");
		Box box1 = Box.createHorizontalBox();
		JLabel l1 = new JLabel("字体:");
		JLabel l2 = new JLabel("字形:");
		JLabel l3 = new JLabel("大小:");
		l1.setPreferredSize(new Dimension(165, 14));
		l1.setMaximumSize(new Dimension(165, 14));
		l1.setMinimumSize(new Dimension(165, 14));
		l2.setPreferredSize(new Dimension(95, 14));
		l2.setMaximumSize(new Dimension(95, 14));
		l2.setMinimumSize(new Dimension(95, 14));
		l3.setPreferredSize(new Dimension(80, 14));
		l3.setMaximumSize(new Dimension(80, 14));
		l3.setMinimumSize(new Dimension(80, 14));
		box1.add(l1);
		box1.add(l2);
		box1.add(l3);
		Box box2 = Box.createHorizontalBox();
		fontText.setPreferredSize(new Dimension(160, 20));
		fontText.setMaximumSize(new Dimension(160, 20));
		fontText.setMinimumSize(new Dimension(160, 20));
		box2.add(fontText);
		box2.add(Box.createHorizontalStrut(5));
		styleText.setPreferredSize(new Dimension(90, 20));
		styleText.setMaximumSize(new Dimension(90, 20));
		styleText.setMinimumSize(new Dimension(90, 20));
		box2.add(styleText);
		box2.add(Box.createHorizontalStrut(5));
		sizeText.setPreferredSize(new Dimension(80, 20));
		sizeText.setMaximumSize(new Dimension(80, 20));
		sizeText.setMinimumSize(new Dimension(80, 20));
		box2.add(sizeText);
		Box box3 = Box.createHorizontalBox();
		JScrollPane sp1 = new JScrollPane(fontList);
		sp1.setPreferredSize(new Dimension(160, 100));
		sp1.setMaximumSize(new Dimension(160, 100));
		sp1.setMaximumSize(new Dimension(160, 100));
		box3.add(sp1);
		box3.add(Box.createHorizontalStrut(5));
		JScrollPane sp2 = new JScrollPane(styleList);
		sp2.setPreferredSize(new Dimension(90, 100));
		sp2.setMaximumSize(new Dimension(90, 100));
		sp2.setMinimumSize(new Dimension(90, 100));
		box3.add(sp2);
		box3.add(Box.createHorizontalStrut(5));
		JScrollPane sp3 = new JScrollPane(sizeList);
		sp3.setPreferredSize(new Dimension(80, 100));
		sp3.setMaximumSize(new Dimension(80, 100));
		sp3.setMinimumSize(new Dimension(80, 100));
		box3.add(sp3);
		Box box4 = Box.createHorizontalBox();
		Box box5 = Box.createVerticalBox();
		JPanel box6 = new JPanel(new BorderLayout());
		box5.setBorder(BorderFactory.createTitledBorder("字符集"));
		box6.setBorder(BorderFactory.createTitledBorder("示例"));
		box5.add(chinaButton);
		box5.add(englishButton);
		box5.add(numberButton);
		box5.setPreferredSize(new Dimension(90, 95));
		box5.setMaximumSize(new Dimension(90, 95));
		box5.setMinimumSize(new Dimension(90, 95));
		box6.add(previewText);
		box6.setPreferredSize(new Dimension(250, 95));
		box6.setMaximumSize(new Dimension(250, 95));
		box6.setMinimumSize(new Dimension(250, 95));
		box4.add(box5);
		box4.add(Box.createHorizontalStrut(4));
		box4.add(box6);
		Box box7 = Box.createHorizontalBox();
		box7.add(Box.createHorizontalGlue());
		box7.add(approveButton);
		box7.add(Box.createHorizontalStrut(5));
		box7.add(cancelButton);
		box.add(box1);
		box.add(box2);
		box.add(box3);
		box.add(Box.createVerticalStrut(5));
		box.add(box4);
		box.add(Box.createVerticalStrut(5));
		box.add(box7);
		getContentPane().add(box);
	}
	/**
	 * 按照预设字体显示
	 */
	private void setup() {
		String fontName = font.getFamily();
		int fontStyle = font.getStyle();
		int fontSize = font.getSize();
		/*
		 * 如果预设的文字大小在选择列表中,则通过选择该列表中的某项进行设值,否则直接将预设文字大小写入文本框
		 */
		boolean b = false;
		for (int i = 0; i < sizeArray.length; i++) {
			if (sizeArray[i].equals(String.valueOf(fontSize))) {
				b = true;
				break;
			}
		}
		if(b){
			// 选择文字大小列表中的某项
			sizeList.setSelectedValue(String.valueOf(fontSize), true);
		}else{
			sizeText.setText(String.valueOf(fontSize));
		}
		// 选择字体列表中的某项
		fontList.setSelectedValue(fontName, true);
		// 选择样式列表中的某项
		styleList.setSelectedIndex(fontStyle);
		// 预览默认显示中文字符
		chinaButton.doClick();
		// 显示预览
		setPreview();
	}
	/**
	 * 添加所需的事件监听器
	 */
	private void addListener() {
		sizeText.addFocusListener(new FocusListener() {
			public void focusLost(FocusEvent e) {
				setPreview();
			}
			public void focusGained(FocusEvent e) {
				sizeText.selectAll();
			}
		});
		// 字体列表发生选择事件的监听器
		fontList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if (!e.getValueIsAdjusting()) {
					fontText.setText(String.valueOf(fontList.getSelectedValue()));
					// 设置预览
					setPreview();
				}
			}
		});
		styleList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if (!e.getValueIsAdjusting()) {
					styleText.setText(String.valueOf(styleList.getSelectedValue()));
					// 设置预览
					setPreview();
				}
			}
		});
		sizeList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if (!e.getValueIsAdjusting()) {
					if(!sizeText.isFocusOwner()){
						sizeText.setText(String.valueOf(sizeList.getSelectedValue()));
					}
					// 设置预览
					setPreview();
				}
			}
		});
		// 编码监听器
		EncodeAction ea = new EncodeAction();
		chinaButton.addActionListener(ea);
		englishButton.addActionListener(ea);
		numberButton.addActionListener(ea);
		// 确定按钮的事件监听
		approveButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// 组合字体
				font = groupFont();
				// 设置返回值
				returnValue = APPROVE_OPTION;
				// 关闭窗口
				disposeDialog();
			}
		});
		// 取消按钮事件监听
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				disposeDialog();
			}
		});
	}
	/**
	 * 显示字体选择器
	 * @param owner 上层所有者
	 * @return 该整形返回值表示用户点击了字体选择器的确定按钮或取消按钮,参考本类常量字段APPROVE_OPTION和CANCEL_OPTION
	 */
	public final int showFontDialog(JFrame owner) {
		setLocationRelativeTo(owner);
		setVisible(true);
		return returnValue;
	}
	/**
	 * 返回选择的字体对象
	 * @return 字体对象
	 */
	public final Font getSelectFont() {
		return font;
	}
	/**
	 * 关闭窗口
	 */
	private void disposeDialog() {
		MQFontChooser.this.removeAll();
		MQFontChooser.this.dispose();
	}
	
	/**
	 * 显示错误消息
	 * @param errorMessage 错误消息
	 */
	private void showErrorDialog(String errorMessage) {
		JOptionPane.showMessageDialog(this, errorMessage, "错误", JOptionPane.ERROR_MESSAGE);
	}
	/**
	 * 设置预览
	 */
	private void setPreview() {
		Font f = groupFont();
		previewText.setFont(f);
	}
	/**
	 * 按照选择组合字体
	 * @return 字体
	 */
	private Font groupFont() {
		String fontName = fontText.getText();
		int fontStyle = styleList.getSelectedIndex();
		String sizeStr = sizeText.getText().trim();
		// 如果没有输入
		if(sizeStr.length() == 0) {
			showErrorDialog("字体(大小)必须是有效“数值!");
			return null;
		}
		int fontSize = 0;
		// 通过循环对比文字大小输入是否在现有列表内
		for (int i = 0; i < sizeArray.length; i++) {
			if(sizeStr.equals(sizeArray[i])){
				fontSize = sizeIntArray[i];
				break;
			}
		}
		// 没有在列表内
		if (fontSize == 0) {
			try{
				fontSize = Integer.parseInt(sizeStr);
				if(fontSize < 1){
					showErrorDialog("字体(大小)必须是有效“数值”!");
					return null;
				}
			}catch (NumberFormatException nfe) {
				showErrorDialog("字体(大小)必须是有效“数值”!");
				return null;
			}
		}
		return new Font(fontName, fontStyle, fontSize);
	}
	
	/**
	 * 编码选择事件的监听动作
	 * @author 米强
	 *
	 */
	class EncodeAction implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (e.getSource().equals(chinaButton)) {
				previewText.setText(CHINA_STRING);
			} else if (e.getSource().equals(englishButton)) {
				previewText.setText(ENGLISH_STRING);
			} else {
				previewText.setText(NUMBER_STRING);
			}
		}
	}
	
}

 

 

 
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
/**
 * 字体选择器测试类
 * @author 米强
 *
 */
public class TestMains extends JFrame {
	private JTextArea text = null;
	private JButton button = null;
	static {
		try {
			// 请配合Look And Feel使用本组件,可得到更好的效果
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
	}
	
	public TestMains() {
		text = new JTextArea("五星红旗迎风飘扬,/n胜利歌声多么响亮;/n歌唱我们亲爱的祖国,/n从今走向繁荣富强。/n歌唱我们亲爱的祖国,/n从今走向繁荣富强。/n/n越过高山,/n越过平原,/n跨过奔腾的黄河长江;/n宽广美丽的土地,/n是我们亲爱的家乡,/n英雄的人民站起来了!/n我们团结友爱坚强如钢。");
		System.out.println(text.getFont());
		button = new JButton("设置字体");
		// 给按钮添加动作事件监听
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// 构造字体选择器,参数字体为预设值
				MQFontChooser fontChooser = new MQFontChooser(text.getFont());
				// 打开一个字体选择器窗口,参数为父级所有者窗体。返回一个整型,代表设置字体时按下了确定或是取消,可参考MQFontChooser.APPROVE_OPTION和MQFontChooser.CANCEL_OPTION
				int returnValue = fontChooser.showFontDialog(TestMains.this);
				// 如果按下的是确定按钮
				if (returnValue == MQFontChooser.APPROVE_OPTION) {
					// 获取选择的字体
					Font font = fontChooser.getSelectFont();
					// 将字体设置到JTextArea中
					text.setFont(font);
				}
			}
		});
		getContentPane().add(new JScrollPane(text));
		getContentPane().add(button, BorderLayout.SOUTH);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(500, 300);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	public static void main(String[] args) {
		new TestMains();
	}
}

 

抱歉!评论已关闭.