Tips/LookAndFeelDebugAgent の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Tips/LookAndFeelDebugAgent へ行く。
- Tips/LookAndFeelDebugAgent の差分を削除
--- title: SwingアプリケーションのLookAndFeelを外部から切り替える author: aterai pubdate: 2008-11-28 description: SwingアプリケーションのLookAndFeelをagentを使って外部から切り替えてデバッグします。 --- #contents * Summary [#summary] `Swing`アプリケーションの`LookAndFeel`を`agent`を使って外部から切り替えてデバッグします。 - [https://ateraimemo.com/data/swing/lnfagent-1.0.1.jar lnfagent-1.0.1.jar] - [https://ateraimemo.com/data/swing/LookAndFeelDebugAgent-1.0.1.zip LookAndFeelDebugAgent-1.0.1.zip] #ref(https://lh5.googleusercontent.com/_9Z4BYR88imo/TT_f_Hrp06I/AAAAAAAAAzQ/zeH8FoIfM4A/s800/LookAndFeelDebugAgent.png) // #ref(https://lh5.googleusercontent.com/_9Z4BYR88imo/TT_f_Hrp06I/AAAAAAAAAzQ/zeH8FoIfM4A/s800/LookAndFeelDebugAgent.png) #ref(https://ateraimemo.com/data/swing/LookAndFeelDebugAgent.png) * ソースコード [#sourcecode] #code{{ package swinghelper; import java.awt.*; import java.awt.event.ActionEvent; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.Optional; import java.util.logging.Logger; import javax.swing.*; import com.formdev.flatlaf.*; public class LookAndFeelDebugAgent { public static Component makeUI() { Box box = LookAndFeelUtils.createLookAndFeelBox(); box.add(Box.createVerticalGlue()); box.setBorder(BorderFactory.createEmptyBorder(5, 25, 5, 25)); return box; } public static void premain(String args) { EventQueue.invokeLater(() -> { JFrame frame = new JFrame("LookAndFeelDebugAgent"); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); frame.getContentPane().add(makeUI()); frame.pack(); frame.setVisible(true); }); } } final class LookAndFeelUtils { private static String lookAndFeel = UIManager.getLookAndFeel().getClass().getName(); private LookAndFeelUtils() { /* Singleton */ } public static Box createLookAndFeelBox() { Box box = Box.createVerticalBox(); ButtonGroup buttonGroup = new ButtonGroup(); for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { AbstractButton b = makeButton(info); initLookAndFeelAction(info, b); box.add(b); buttonGroup.add(b); } for (Class<?> clz : Arrays.asList(FlatLightLaf.class, FlatDarkLaf.class)) { String full = clz.getName(); String name = full.substring(full.lastIndexOf('.') + 1); UIManager.LookAndFeelInfo info = new UIManager.LookAndFeelInfo(name, full); AbstractButton b = makeButton(info); initLookAndFeelAction(info, b); box.add(b); buttonGroup.add(b); } return box; } private static AbstractButton makeButton(UIManager.LookAndFeelInfo info) { boolean selected = info.getClassName().equals(lookAndFeel); return new JRadioButton(info.getName(), selected); } public static void initLookAndFeelAction(UIManager.LookAndFeelInfo info, AbstractButton b) { String cmd = info.getClassName(); b.setText(info.getName()); b.setActionCommand(cmd); b.setHideActionText(true); b.addActionListener(e -> setLookAndFeel(cmd)); } private static void setLookAndFeel(String newLookAndFeel) { String oldLookAndFeel = lookAndFeel; if (!oldLookAndFeel.equals(newLookAndFeel)) { try { UIManager.setLookAndFeel(newLookAndFeel); lookAndFeel = newLookAndFeel; } catch (UnsupportedLookAndFeelException ignored) { Toolkit.getDefaultToolkit().beep(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { Logger.getGlobal().severe(ex::getMessage); return; } updateLookAndFeel(); } } private static void updateLookAndFeel() { for (Window window : Window.getWindows()) { SwingUtilities.updateComponentTreeUI(window); } } } }} * Explanation [#explanation] - アプリケーションと同時に`Look And Feel`を切り替えるための別パネルを起動して、対象アプリケーションのソースコードを変更することなく`LookAndFeel`の変更がテスト可能 - このサンプルではデフォルト以外の`Look And Feel`として`FlatLightLaf`と`FlatDarkLaf`を追加して以下のように`Boot-Class-Path`を指定してコンパイルしている #code{{ <target name="package" depends="compile"> <jar jarfile="${build.dir}/${name}-${version}.jar" basedir="${build.dest}"> <manifest> <!--attribute name="Main-Class" value="${main.class}" /--> <!--attribute name="Agent-Class" value="${main.class}" /--> <attribute name="Premain-Class" value="${main.class}" /> <attribute name="Class-Path" value="${runtime.classpath}" /> <attribute name="Can-Retransform-Classes" value="true"/> <attribute name="Boot-Class-Path" value="flatlaf-3.5.jar" /> </manifest> </jar> </target> }} - `javaagent`を使用するため、`JDK 1.6`以上で以下のように起動する #code{{ java -javaagent:lnfagent1.0.1.jar -jar example.jar }} * Reference [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/java/lang/instrument/package-summary.html java.lang.instrument (Java Platform SE 8)] * Comment [#comment] #comment #comment