Tips/LookAndFeelDebugAgent のバックアップの現在との差分(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Tips/LookAndFeelDebugAgent へ行く。
- 1 (2011-01-26 (水) 17:49:53)
- 2 (2013-10-31 (木) 17:00:38)
- 3 (2014-09-03 (水) 18:19:49)
- 4 (2014-11-08 (土) 01:41:12)
- 5 (2015-03-27 (金) 21:45:05)
- 6 (2017-10-27 (金) 16:26:13)
- 7 (2018-05-30 (水) 21:02:06)
- 8 (2018-10-12 (金) 17:40:15)
- 9 (2025-01-03 (金) 08:57:02)
- 10 (2025-01-03 (金) 09:02:38)
- 11 (2025-01-03 (金) 09:03:21)
- 12 (2025-01-03 (金) 09:04:02)
- 13 (2025-01-19 (日) 09:59:04)
- 14 (2025-06-19 (木) 12:41:37)
- 15 (2025-06-19 (木) 12:43:47)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:SwingアプリケーションのLookAndFeelを外部から切り替える #navi(../) RIGHT:Posted by &author(aterai); at 2008-11-28 *SwingアプリケーションのLookAndFeelを外部から切り替える [#mabcbff3] #adsense2 --- title: SwingアプリケーションのLookAndFeelを外部から切り替える author: aterai pubdate: 2008-11-28 description: SwingアプリケーションのLookAndFeelをagentを使って外部から切り替えてデバッグします。 --- #contents - [http://terai.xrea.jp/data/swing/lnfagent.jar lnfagent.jar] - [http://terai.xrea.jp/data/swing/LookAndFeel_Debug_Agent_src.zip src.zip] * Summary [#summary] `Swing`アプリケーションの`LookAndFeel`を`agent`を使って外部から切り替えてデバッグします。 #ref(https://lh5.googleusercontent.com/_9Z4BYR88imo/TT_f_Hrp06I/AAAAAAAAAzQ/zeH8FoIfM4A/s800/LookAndFeelDebugAgent.png) //#contents(none) - [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] **概要 [#u5a5b58a] SwingアプリケーションのLookAndFeelを agent を使って外部から切り替えてデバッグします。 // #ref(https://lh5.googleusercontent.com/_9Z4BYR88imo/TT_f_Hrp06I/AAAAAAAAAzQ/zeH8FoIfM4A/s800/LookAndFeelDebugAgent.png) #ref(https://ateraimemo.com/data/swing/LookAndFeelDebugAgent.png) **ソースコード [#n6f61d1b] * ソースコード [#sourcecode] #code{{ package swinghelper; import java.awt.*; import java.awt.event.*; import java.lang.instrument.*; 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 void premain(String args) throws Exception { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } 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); }); } public static void createAndShowGUI() { ButtonGroup group = new ButtonGroup(); Box box = Box.createVerticalBox(); for(LookAndFeelEnum lnf : LookAndFeelEnum.values()) { JRadioButton rb = new JRadioButton(new ChangeLookAndFeelAction(lnf)); group.add(rb); box.add(rb); } box.add(Box.createVerticalGlue()); box.setBorder(BorderFactory.createEmptyBorder(5,25,5,25)); } JFrame frame = new JFrame("LnF"); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); frame.getContentPane().add(box); frame.pack(); frame.setVisible(true); final class LookAndFeelUtils { private static String lookAndFeel = UIManager.getLookAndFeel().getClass().getName(); private LookAndFeelUtils() { /* Singleton */ } private static enum LookAndFeelEnum { Metal ("javax.swing.plaf.metal.MetalLookAndFeel"), Mac ("com.sun.java.swing.plaf.mac.MacLookAndFeel"), Motif ("com.sun.java.swing.plaf.motif.MotifLookAndFeel"), Windows("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"), GTK ("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"), Nimbus ("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); private final String clazz; private LookAndFeelEnum(String clazz) { this.clazz = clazz; 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); } public String getClassName() { return clazz; 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 class ChangeLookAndFeelAction extends AbstractAction{ private final String lnf; protected ChangeLookAndFeelAction(LookAndFeelEnum lnfe) { super(lnfe.toString()); this.lnf = lnfe.getClassName(); this.setEnabled(isAvailableLookAndFeel(lnf)); } private static boolean isAvailableLookAndFeel(String lnf) { try{ Class lnfClass = Class.forName(lnf); LookAndFeel newLnF = (LookAndFeel)(lnfClass.newInstance()); return newLnF.isSupportedLookAndFeel(); }catch(Exception e) { return false; 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(); } @Override public void actionPerformed(ActionEvent e) { try{ UIManager.setLookAndFeel(lnf); }catch(Exception ex) { ex.printStackTrace(); System.out.println("Failed loading L&F: " + lnf); } for(Frame f:Frame.getFrames()) { if(f instanceof JFrame) { SwingUtilities.updateComponentTreeUI(f); f.pack(); } } } private static void updateLookAndFeel() { for (Window window : Window.getWindows()) { SwingUtilities.updateComponentTreeUI(window); } } } }} **解説 [#rcf0b33c] Look And Feel を切り替えるためのパネルが一緒に起動し、対象アプリケーションのソースコードを変更することなく、LookAndFeel の変更をテストすることが出来ます。 * Description [#description] - アプリケーションと同時に`Look And Feel`を切り替えるための別パネルを起動して、対象アプリケーションのソースコードを変更することなく`LookAndFeel`の変更がテスト可能 javaagentを使うので、JDK 1.6 以上で以下のように起動します。 - このサンプルではデフォルト以外の`Look And Feel`として`FlatLightLaf`と`FlatDarkLaf`を追加して以下のように`Boot-Class-Path`を指定してコンパイルしている #code{{ java -javaagent:lnfagent.jar -jar example.jar <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> }} //**参考リンク **コメント [#ff4ef8a7] - `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