---
category: swing
folder: HexFormatterSpinner
title: JSpinnerの表記を16進数にする
tags: [JSpinner, DefaultFormatter, Font]
author: aterai
pubdate: 2013-06-03T04:18:20+09:00
description: JSpinnerの表記を16進数にして、そのUnicodeコードポイントに割り当てられた文字を表示します。
image: https://lh4.googleusercontent.com/-eTZU_kuJGK4/UauUgRcPuTI/AAAAAAAABtc/7FNouA9JcLI/s800/HexFormatterSpinner.png
---
* 概要 [#summary]
`JSpinner`の表記を`16`進数にして、その`Unicode`コードポイントに割り当てられた文字を表示します。

#download(https://lh4.googleusercontent.com/-eTZU_kuJGK4/UauUgRcPuTI/AAAAAAAABtc/7FNouA9JcLI/s800/HexFormatterSpinner.png)

* サンプルコード [#sourcecode]
#code(link){{
private static DefaultFormatterFactory makeFFactory() {
  DefaultFormatter formatter = new DefaultFormatter() {
    @Override public Object stringToValue(String text) throws ParseException {
      Pattern pattern = Pattern.compile("^\\s*(\\p{XDigit}{1,6})\\s*$");
      Matcher matcher = pattern.matcher(text);
      if (matcher.find()) {
        Integer iv = Integer.valueOf(text, 16);
        if (iv <= Character.MAX_CODE_POINT) {
          return iv;
        }
      }
      Toolkit.getDefaultToolkit().beep();
      throw new ParseException(text, 0);
      // try {
      //   return Integer.valueOf(text, 16);
      // } catch (NumberFormatException ex) {
      //   Toolkit.getDefaultToolkit().beep();
      //   ParseException wrap = new ParseException(text, 0);
      //   wrap.initCause(ex);
      //   throw wrap;
      // }
    }
    @Override public String valueToString(Object value) throws ParseException {
      return String.format("%06X", (Integer) value);
    }
  };
  formatter.setValueClass(Integer.class);
  formatter.setOverwriteMode(true);
  return new DefaultFormatterFactory(formatter);
}
}}

* 解説 [#explanation]
上記のサンプルでは、`DefaultFormatter#stringToValue(String)`と`DefaultFormatter#valueToString(Object)`をオーバーライドして、`0x0`から`0x10FFFF`(`Character.MAX_CODE_POINT`)までの整数を`16`進数で表示する`Formatter`を作成して`JSpinner`に設定しています。

- [https://moji.or.jp/mojikiban/font/ IPAmj明朝]と[https://moji.or.jp/ipafont/ IPAex明朝]フォントがインストールされている場合、その文字の形の違いが比較可能
- `JSpinner`から取得した数値(コードポイント)から文字を生成する時、サロゲートペアなどの基本多言語面(`BMP`)外に対応する必要がある
-- [https://docs.oracle.com/javase/tutorial/i18n/text/usage.html Sample Usage (The Java™ Tutorials > Internationalization > Working with Text)]
#code{{
int code = ((Integer) spinner.getValue()).intValue();
// char[] ca = Character.toChars(code);
String str = new String(Character.toChars(code));
}}

- %%`8.0.212-amzn`で実行するとゲタ文字や一部の表示が壊れる?%%
- `8.0.222-amzn`で修正済み
-- `11.0.3-amzn`は正常
-- パネルのリサイズで再描画されると正常に戻ったり壊れたりする場合がある?

* 参考リンク [#reference]
- [[Fontのアウトラインを取得して文字列の内部を修飾する>Swing/LineSplittingLabel]]
- [https://moji.or.jp/mojikiban/font/ IPAmj明朝フォント | 一般社団法人 文字情報技術促進協議会]
- [https://moji.or.jp/ipafont/ IPAexフォントおよびIPAフォントについて | 一般社団法人 文字情報技術促進協議会]
- [http://f.hatena.ne.jp/NAOI/20130411131759 IPAmj明朝とIPAex明朝で形の違う字 NAOI's fotolife - 20130411131759]
- [https://f.hatena.ne.jp/NAOI/20130411131759 IPAmj明朝とIPAex明朝で形の違う字 NAOI's fotolife - 20130411131759]

* コメント [#comment]
#comment
#comment