JFormattedTextFieldに等幅フォントを設定する
Total: 779
, Today: 2
, Yesterday: 8
Posted by aterai at
Last-modified:
概要
JFormattedTextField
やJTextField
の推奨サイズを列数とフォントのサイズから計算します。
Screenshot
Advertisement
サンプルコード
String code = "BC89FE5A";
JFormattedTextField field0 = new JFormattedTextField(code);
field0.setHorizontalAlignment(SwingConstants.RIGHT);
field0.setColumns(8);
JFormattedTextField field1 = new JFormattedTextField(code);
field1.setHorizontalAlignment(SwingConstants.RIGHT);
Font mono = new Font(Font.MONOSPACED, Font.PLAIN, field1.getFont().getSize());
field1.setFont(mono);
field1.setColumns(8);
JFormattedTextField field2 = new JFormattedTextField(code);
field2.setHorizontalAlignment(SwingConstants.RIGHT);
Map<TextAttribute, Object> attr = new ConcurrentHashMap<>();
attr.put(TextAttribute.TRACKING, -.021f);
field2.setFont(mono.deriveFont(attr));
field2.setColumns(8);
JFormattedTextField field3 = new JFormattedTextField(code) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width += 2;
return d;
}
};
field3.setHorizontalAlignment(SwingConstants.RIGHT);
field3.setFont(mono);
field3.setColumns(8);
JFormattedTextField field4 = new JFormattedTextField(code);
field4.setHorizontalAlignment(SwingConstants.RIGHT);
field4.setFont(mono);
field4.setColumns(9);
View in GitHub: Java, Kotlin解説
Default
- 日本語
Windows
環境のデフォルトでは12px
のMS UI Gothic
が使用され、小文字m
の幅が9px
(12/2=6px
にならない)となるので、余白を除いた推奨サイズ幅はJFormattedTextField#setColumns(8)
で設定した8
列を掛けて72px
となるUbuntu
環境では13px*8列=104px
Font#getStringBounds("BC89FE5A", frc)
で計算される実際の文字列幅は56.0
(7px*8文字
?)となるので推奨サイズ幅に余りが発生してしまう
- 日本語
// @see JTextField
protected int getColumnWidth() {
if (columnWidth == 0) {
FontMetrics metrics = getFontMetrics(getFont());
columnWidth = metrics.charWidth('m');
}
return columnWidth;
}
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
if (columns != 0) {
Insets insets = getInsets();
size.width = columns * getColumnWidth() + insets.left + insets.right;
}
return size;
}
MONOSPACED
new Font(Font.MONOSPACED, Font.PLAIN, field1.getFont().getSize())
で作成した等幅フォントを設定し、小文字m
の幅が7px
となるので、余白を除いた推奨サイズ幅はJFormattedTextField#setColumns(8)
で設定した8
列を掛けて56px
となるFont#getStringBounds("BC89FE5A", frc)
で計算される実際の文字列幅は56.0
(7px*8文字
?)と推奨サイズ幅と一致するため、キャレット1px
?分が不足して文字列選択などでスクロールが発生する
TRACKING-.011f
Font
のトラッキングを変更して-1.1%
字詰めを適用し、文字列幅を54.944px
と1px
余裕を持たせるよう設定Java 17
環境では1px
の余裕では足りず-2%
字詰めして2px
余裕がないとスクロールが発生してしまう?
PreferredSize+1
JFormattedTextField#getPreferredSize()
をオーバーライドして余白を除く推奨サイズ幅をプラス1px
した値となるよう設定Java 17
環境では1px
の余裕では足りず2px
余裕がないとスクロールが発生してしまう?
Columns+1
JFormattedTextField#setColumns(8+1)
と列を1
文字分増加してスクロールの発生を防ぐよう設定- JColorChooserのRGB色選択パネル内に表示される16進数カラーコードにAlpha値を追加するのように
16
進数カラーコードを表示するJFormattedTextField
をオーバーライドしたり、推奨サイズを参照しないレイアウトマネージャを使用することが難しい場合はJFormattedTextField#setColumns(...)
で列数を1
文字分増加する方法がスクロールの発生を防ぐ最も手軽な回避方法かもしれない