天天看點

Java Swing寫的字型選擇器,仿記事本中的字型控件

Java Swing 寫的字型選擇器,仿記事本中的字型控件,使用操作方法與檔案選擇器JFileChooser基本相同。

Java Swing寫的字型選擇器,仿記事本中的字型控件

package net.miqiang.gui;

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);

}

}

}

}

下面是一個測試類,需要單獨建一個TestMain.java檔案

package net.miqiang.gui;

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 TestMain 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 TestMain() {

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(TestMain.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 TestMain();

}

}