4 * Copyright(c) 2009 olyutorskii
\r
5 * $Id: Monodizer.java 963 2009-12-20 12:55:11Z olyutorskii $
\r
8 package jp.sourceforge.jindolf;
\r
10 import java.awt.Component;
\r
11 import java.awt.Font;
\r
12 import java.awt.font.TextAttribute;
\r
13 import java.beans.PropertyChangeEvent;
\r
14 import java.beans.PropertyChangeListener;
\r
15 import java.util.Collections;
\r
16 import java.util.Map;
\r
17 import javax.swing.ComboBoxEditor;
\r
18 import javax.swing.JComboBox;
\r
19 import javax.swing.JComponent;
\r
20 import javax.swing.text.JTextComponent;
\r
23 * Swingコンポーネントのフォント等幅化。
\r
26 public final class Monodizer implements PropertyChangeListener{
\r
28 /** フォント変更時のプロパティ名。 */
\r
29 public static final String PROPNAME_FONT = "font";
\r
30 /** L&F変更時のプロパティ名。 */
\r
31 public static final String PROPNAME_UI = "UI";
\r
32 /** Font.MONOSPACED代替品。 */
\r
33 public static final String FAMILY_MONO = "Monospaced";
\r
35 private static final Map<TextAttribute, String> TEXTATTR_MONO =
\r
36 Collections.singletonMap(TextAttribute.FAMILY, FAMILY_MONO);
\r
38 private static final Monodizer CHANGER = new Monodizer();
\r
44 * @return 等幅フォントならtrue
\r
46 public static boolean isMonospaced(Font font){
\r
47 Map<TextAttribute, ?> attrMap = font.getAttributes();
\r
49 Object attr = attrMap.get(TextAttribute.FAMILY);
\r
50 if( ! (attr instanceof String) ) return false;
\r
52 String family = (String) attr;
\r
53 if(family.equals(FAMILY_MONO)) return true;
\r
60 * 等幅以外の属性は可能な限り保持する。
\r
61 * @param font 任意のフォント
\r
64 public static Font deriveMonoFont(Font font){
\r
65 Font monofont = font.deriveFont(TEXTATTR_MONO);
\r
70 * 任意のコンポーネントをフォント等幅化する。
\r
71 * L&F変更に対処するためのリスナ組み込みも行われる。
\r
72 * @param comp コンポーネント
\r
74 public static void monodize(JComponent comp){
\r
75 Font oldFont = comp.getFont();
\r
76 Font newFont = deriveMonoFont(oldFont);
\r
77 comp.setFont(newFont);
\r
79 modifyComponent(comp);
\r
81 comp.addPropertyChangeListener(PROPNAME_FONT, CHANGER);
\r
82 comp.addPropertyChangeListener(PROPNAME_UI, CHANGER);
\r
91 * @param comp コンポーネント
\r
93 private static void modifyComponent(JComponent comp){
\r
94 if(comp instanceof JTextComponent){
\r
95 JTextComponent textComp = (JTextComponent) comp;
\r
96 modifyTextComponent(textComp);
\r
97 }else if(comp instanceof JComboBox){
\r
98 JComboBox combo = (JComboBox) comp;
\r
99 modifyComboBox(combo);
\r
106 * テキストコンポーネントへの微修正を行う。
\r
107 * @param textComp テキストコンポーネント
\r
109 private static void modifyTextComponent(JTextComponent textComp){
\r
110 if( ! textComp.isEditable() ){
\r
111 textComp.setCaretPosition(0);
\r
117 * コンボボックスのエディタを等幅化する。
\r
118 * @param comboBox コンボボックス
\r
120 private static void modifyComboBox(JComboBox comboBox){
\r
121 ComboBoxEditor editor = comboBox.getEditor();
\r
122 if(editor == null) return;
\r
124 Component editComp = editor.getEditorComponent();
\r
125 if( ! (editComp instanceof JTextComponent) ) return;
\r
126 JTextComponent textEditor = (JTextComponent) editComp;
\r
128 Font oldFont = textEditor.getFont();
\r
129 Font newFont = deriveMonoFont(oldFont);
\r
130 textEditor.setFont(newFont);
\r
132 modifyTextComponent(textEditor);
\r
139 * @param event フォント変更イベント
\r
141 public void propertyChange(PropertyChangeEvent event){
\r
142 Object source = event.getSource();
\r
143 if( ! (source instanceof JComponent) ) return;
\r
144 JComponent comp = (JComponent) source;
\r
146 String propName = event.getPropertyName();
\r
149 if(PROPNAME_FONT.equals(propName)){
\r
150 Object newValue = event.getNewValue();
\r
151 if( ! (newValue instanceof Font) ) return;
\r
152 newFont = (Font) newValue;
\r
153 }else if(PROPNAME_UI.equals(propName)){
\r
154 newFont = comp.getFont();
\r
159 Font monoFont = deriveMonoFont(newFont);
\r
160 comp.setFont(monoFont); // 再帰は起きないはず…
\r
162 modifyComponent(comp);
\r
170 private Monodizer(){
\r