JColorChooserのRGB色選択パネル内に表示される16進数カラーコードにAlpha値を追加する
Total: 742
, Today: 1
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
JColorChooser
のRGB
色選択パネル内に表示される16
進数カラーコードをRGB6
桁からAlpha
値を追加したRGBA8
桁に変更します。
Screenshot
Advertisement
サンプルコード
UIManager.put("ColorChooser.rgbHexCodeText", "#RGBA:");
JButton button = new JButton("open JColorChooser");
button.addActionListener(e -> {
JColorChooser cc = new JColorChooser();
cc.setColor(new Color(0xFF_FF_00_00, true));
AbstractColorChooserPanel[] panels = cc.getChooserPanels();
List<AbstractColorChooserPanel> choosers =
new ArrayList<>(Arrays.asList(panels));
AbstractColorChooserPanel ccp = choosers.get(3);
// Java 9: if (ccp.isColorTransparencySelectionEnabled()) {
for (Component c : ccp.getComponents()) {
if (c instanceof JFormattedTextField) {
// removeFocusListeners(c);
// ValueFormatter.init(8, true, (JFormattedTextField) c);
ValueFormatter.init((JFormattedTextField) c);
}
}
cc.setChooserPanels(choosers.toArray(new AbstractColorChooserPanel[0]));
ColorTracker ok = new ColorTracker(cc);
Component parent = getRootPane();
String title = "JColorChooser";
JDialog dialog = JColorChooser.createDialog(
parent, title, true, cc, ok, null);
dialog.addComponentListener(new ComponentAdapter() {
@Override public void componentHidden(ComponentEvent e) {
((Window) e.getComponent()).dispose();
}
});
dialog.setVisible(true);
Color color = ok.getColor();
if (color != null) {
label.setBackground(color);
}
});
// copied from javax/swing/colorchooser/ValueFormatter.java
class ValueFormatter extends JFormattedTextField.AbstractFormatter
implements FocusListener {
private final transient DocumentFilter filter = new DocumentFilter() {
// ...
};
public static void init(JFormattedTextField text) {
ValueFormatter formatter = new ValueFormatter();
text.setColumns(8);
text.setFormatterFactory(new DefaultFormatterFactory(formatter));
text.setHorizontalAlignment(SwingConstants.RIGHT);
text.setMinimumSize(text.getPreferredSize());
text.addFocusListener(formatter);
}
@Override public Object stringToValue(String text) throws ParseException {
try {
int r = Integer.parseInt(text.substring(0, 2), 16);
int g = Integer.parseInt(text.substring(2, 4), 16);
int b = Integer.parseInt(text.substring(4, 6), 16);
int a = Integer.parseInt(text.substring(6), 16);
return (a << 24) | (r << 16) | (g << 8) | b;
// return Integer.valueOf(argb, 16); // <- NumberFormatException
} catch (NumberFormatException nfe) {
ParseException pe = new ParseException("illegal format", 0);
pe.initCause(nfe);
throw pe;
}
}
@Override public String valueToString(Object object) throws ParseException {
if (object instanceof Integer) {
int value = (Integer) object;
// String str = "00" + Integer.toHexString(value).toUpperCase();
char[] array = new char[8];
for (int i = array.length - 1; i >= 0; i--) {
array[i] = Character.forDigit(value & 0x0F, 16);
value >>= 4;
}
String argb = String.valueOf(array).toUpperCase(Locale.ENGLISH);
return argb.substring(2) + argb.substring(0, 2);
}
throw new ParseException("illegal object", 0);
}
}
View in GitHub: Java, Kotlin解説
- デフォルト
JColorChooser
のRGB
色選択パネルで16
進数色コード(ColorChooser.rgbHexCodeText
)表示に使用されるJFormattedTextField
は6
桁で#RRGGBB
表示 16
進数色コード表示用のJFormattedTextField
を取得して16
進数8
桁(#RRGGBBAA
)を表示するようなFormatter
を設定JColorChooser#getChooserPanels()
でAbstractColorChooserPanel
の配列を取得- この配列の
3
番目からRGB
色選択パネルを取得 AbstractColorChooserPanel#getComponents()
で子要素のJFormattedTextField
を取得- 赤青緑アルファ用の
JSpinner
が使用するJFormattedTextField
を取得しないよう注意
- 赤青緑アルファ用の
16
進数色コード表示用のJFormattedTextField
にsetFormatterFactory(new DefaultFormatterFactory(formatter))
で16
進数8
桁(#RRGGBBAA
)を表示するFormatter
を設定- この
Formatter
はjavax/swing/colorchooser/ValueFormatter.java
を参考に作成
- この
valueToString(Object)
でargb
形式のInteger
色値を16
進数色コード文字列に変換後、argb.substring(2) + argb.substring(0, 2)
でrgba
形式に並び替えるstringToValue(String)
でrgba
形式の16
進数色コード文字列をred
,green
,blue
,alpha
を表す文字列に分解してInteger.parseInt(...)
でInteger
化し、(a << 24) | (r << 16) | (g << 8) | b
で順序を並び変えて結合してargb
形式のInteger
色値に変換16
進数6
桁で使用しているInteger.valueOf(argbStr, 16)
を8
桁で使用するとint
の最大値を超えてNumberFormatException
が発生する場合があるInteger.parseUnsignedInt(argbStr, 16)
で回避可能
参考リンク
- RGBA color model - Wikipedia
- JColorChooserのSwatchesタブに配置されたRecentカラーパレットを保存、復元する
- JColorChooserのRGB色選択パネルでアルファ設定用のJSliderとJSpinnerを無効化する
- HTMLの16進数カラーコードからColorを生成する