Java Swingでテキスト変換時に、その変換中の文字の色を変えることはできるのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
SELECTED_CONVERTED_TEXT_HIGHLIGHT
が「変換中の文字の色」のようです。
InputMethodHighlight (Java SE 23 & JDK 23)
ただStyle
はnullで、mapInputMethodHighlight
で実際のStyle
が取れるようです。
Toolkit (Java SE 23 & JDK 23)
手元のWindows11では白文字に濃い青背景でした。
jdk/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java · openjdk/jdk
ここまではすぐわかったのですが、肝心の(真っ当な)変更方法がわかりませんでしたorz
直接変えるような手段はおそらくないと思います(全部決め打ちで差し込む隙がない)
描画側(JTextField
等)でどうにかすることは可能だと思いますが、簡単ではなさそうです(わたしは挫折しましたw
(今後使えなくなることが確定している)真っ黒な方法でよければ、手元のOpenJDK23では動きました(特に勧める気はないです)
finalなフィールドの値をUnsafeで無理やり書き換える - R42日記
JEP 471: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal
java
1import javax.swing.*; 2import java.awt.*; 3import java.awt.font.TextAttribute; 4import java.awt.im.InputMethodHighlight; 5import java.lang.reflect.Field; 6import java.lang.reflect.Method; 7import java.util.HashMap; 8 9public class Sample extends JFrame { 10 public static void main(String[] args) { 11 new Sample().setVisible(true); 12 } 13 14 Sample() { 15 setSize(400, 200); 16 setLocationRelativeTo(null); 17 setDefaultCloseOperation(EXIT_ON_CLOSE); 18 19 add(new JTextField(), BorderLayout.NORTH); 20 add(new JTextArea()); 21 var panel = new JPanel(new GridLayout(1, 2)); 22 add(panel, BorderLayout.SOUTH); 23 var button1 = new JButton("白抜き赤"); 24 panel.add(button1); 25 var button2 = new JButton("実線"); 26 panel.add(button2); 27 28 button1.addActionListener(e -> { 29 var map = new HashMap<TextAttribute, Object>(4); 30 map.put(TextAttribute.FOREGROUND, new Color(128, 0, 0)); 31 map.put(TextAttribute.BACKGROUND, Color.WHITE); 32 map.put(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON); 33 map.put(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_ONE_PIXEL); 34// var m = Toolkit.getDefaultToolkit().mapInputMethodHighlight(InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT); 35// var map = new HashMap<TextAttribute, Object>(m); 36// map.put(TextAttribute.FOREGROUND, new Color(128, 0, 0)); 37 38 var highlight = new InputMethodHighlight(true, InputMethodHighlight.CONVERTED_TEXT, 0, map); 39 try { 40 var f = InputMethodHighlight.class.getDeclaredField("SELECTED_CONVERTED_TEXT_HIGHLIGHT"); 41 FinalFieldSetter.getInstance().setStatic(f, highlight); 42 } catch (Exception ignored) { } 43 }); 44 45 button2.addActionListener(e -> { 46 var map = new HashMap<TextAttribute, Object>(1); 47 map.put(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL); 48 49 var highlight = new InputMethodHighlight(true, InputMethodHighlight.CONVERTED_TEXT, 0, map); 50 try { 51 var f = InputMethodHighlight.class.getDeclaredField("SELECTED_CONVERTED_TEXT_HIGHLIGHT"); 52 FinalFieldSetter.getInstance().setStatic(f, highlight); 53 } catch (Exception ignored) { } 54 }); 55 } 56} 57 58// [finalなフィールドの値をUnsafeで無理やり書き換える - R42日記](https://takahashikzn.root42.jp/entry/2014/03/20/212021) 59final class FinalFieldSetter { 60 private static final FinalFieldSetter INSTANCE; 61 static { 62 try { 63 INSTANCE = new FinalFieldSetter(); 64 } catch (ReflectiveOperationException e) { 65 throw new ExceptionInInitializerError(e); 66 } 67 } 68 private final Object unsafeObj; 69 private final Method putObjectMethod; 70 private final Method staticFieldOffsetMethod; 71 private final Method staticFieldBaseMethod; 72 private FinalFieldSetter() throws ReflectiveOperationException { 73 var unsafeClass = Class.forName("sun.misc.Unsafe"); 74 var unsafeField = unsafeClass.getDeclaredField("theUnsafe"); 75 unsafeField.setAccessible(true); 76 unsafeObj = unsafeField.get(null); 77 putObjectMethod = unsafeClass.getMethod("putObject", Object.class, long.class, Object.class); 78 staticFieldOffsetMethod = unsafeClass.getMethod("staticFieldOffset", Field.class); 79 staticFieldBaseMethod = unsafeClass.getMethod("staticFieldBase", Field.class); 80 } 81 public static FinalFieldSetter getInstance() { return INSTANCE; } 82 public void setStatic(Field field, Object value) throws Exception { 83 var fieldBase = staticFieldBaseMethod.invoke(unsafeObj, field); 84 var fieldOffset = (long) staticFieldOffsetMethod.invoke(unsafeObj, field); 85 putObjectMethod.invoke(unsafeObj, fieldBase, fieldOffset, value); 86 } 87}
投稿2024/09/24 12:40
編集2024/09/24 20:44総合スコア9807
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。