Tips/DebugPainterAgent の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Tips/DebugPainterAgent へ行く。
- Tips/DebugPainterAgent の差分を削除
--- title: Swingコンポーネントの再描画をJXLayerのDebugPainterを使ってデバッグ author: aterai pubdate: 2008-06-05 description: JXLayerのDebugPainterを使用したコンポーネントの再描画を可視化するjavaagentでデバッグを行います。 --- #contents * 概要 [#summary] `JXLayer`の`DebugPainter`を使用したコンポーネントの再描画を可視化する`javaagent`でデバッグを行います。 - [https://ateraimemo.com/data/swing/debugpainter.jar debugpainter.jar] - [https://ateraimemo.com/data/swing/debugpainter_src.zip debugpainter_src.zip] #ref(https://lh4.googleusercontent.com/_9Z4BYR88imo/TUFGtJHiIaI/AAAAAAAAAzs/ye6so-pxydw/s800/DebugPainterAgent.png) * ソースコード [#sourcecode] #code{{ package org.jdesktop.swinghelper.layer.demo; import java.awt.*; import java.lang.instrument.*; import javax.swing.*; import org.jdesktop.jxlayer.JXLayer; import org.jdesktop.jxlayer.plaf.ext.DebugRepaintingUI; public class DebugPainterAgent { public static void premain(String args) throws Exception { //System.out.println("premain"); agentmain(args); } public static void agentmain(String args) throws Exception { System.out.println("agentmain start"); new Thread() { @Override public void run() { System.out.println("Thread run"); Frame[] list = Frame.getFrames(); while (list.length==0) { //FIX ME! try { sleep(1000); } catch (Exception e) { e.printStackTrace(); } System.out.print("."); list = Frame.getFrames(); } System.out.println(" "); System.out.println("Loop out"); replaceLayer(); System.out.println("Thread exit"); } } .start(); System.out.println("agentmain end"); } private static void replaceLayer() { for (Frame f:Frame.getFrames()) { if (f instanceof JFrame) { final JFrame frame = (JFrame)f; EventQueue.invokeLater(new Runnable() { @Override public void run() { System.out.println("replace layer"); JComponent c = (JComponent)frame.getContentPane(); JXLayer<JComponent> layer = new JXLayer<JComponent>(c); layer.setUI(new DebugRepaintingUI()); frame.setContentPane(layer); frame.pack(); } }); } } } } }} * 解説 [#explanation] 例えば、`repaint`が無限ループしているバグのあるサンプルを以下のように起動すると、`JLabel`の描画が無駄に繰り返され、`CPU`の使用率も異常になっている様子がすぐに分かります。 //--debugpainter.batをクリックします。 //--このデモに添付している TableCellProgressBar などは、JTableのセルや、ポップアップメニューを開いたときの再描画が分かりやすくて面白いかも。 - [https://java.net/projects/jxlayer Jxlayer — Project Kenai]から`jxlayer.jar`をダウンロードし、カレントもしくは、`.\lib`以下に配置 - [https://ateraimemo.com/data/swing/debugpainter.jar debugpainter.jar]をダウンロードし、カレントディレクトリに配置 -- または、ソース([https://ateraimemo.com/data/swing/debugpainter_src.zip debugpainter_src.zip])をダウンロードし、コンパイルして生成 #code{{ javac RepaintLoopTest.java java -javaagent:debugpainter.jar RepaintLoopTest REM java -javaagent:debugpainter.jar -jar example.jar }} #code{{ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; public class RepaintLoopTest { public JComponent makeUI() { String[] columnNames = {"String", "Integer", "Boolean"}; Object[][] data = { {"aaa", 12, true}, {"bbb", 5, false}, {"CCC", 92, true}, {"DDD", 0, false} }; DefaultTableModel model = new DefaultTableModel(data, columnNames) { @Override public Class<?> getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; JTable table = new JTable(model); table.setAutoCreateRowSorter(true); JLabel label = new JLabel("aaaaaaaaa") { int h = 10; int d = 1; @Override protected void paintComponent(Graphics g) { super.paintComponent(g); repaint(); //BUG: an infinite repaint loop } }; JPanel p = new JPanel(new BorderLayout()); p.add(new JScrollPane(table)); p.add(label, BorderLayout.SOUTH); p.setPreferredSize(new Dimension(320, 240)); return p; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new RepaintLoopTest().makeUI()); f.pack(); //setSize(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } } }} * 参考リンク [#reference] - %%[https://jxlayer.dev.java.net/ jxlayer: Project Home Page]%% - %%[https://java.net/projects/jxlayer Jxlayer — Project Kenai]%% - %%[http://weblogs.java.net/blog/alexfromsun/archive/2007/11/debug_swing_rep.html Alexander Potochkin's Blog: Debug Swing repainting]%% - %%[http://weblogs.java.net/blog/alexfromsun/archive/2008/06/the_new_jxlayer.html Alexander Potochkin's Blog: JXLayer 3.0 - Getting started]%% - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JComponent.html#setDebugGraphicsOptions-int- JComponent (Java Platform SE 8)] -- [http://www.java2s.com/Tutorial/Java/0240__Swing/DebugGraphics.htm DebugGraphics : DebugGraphics « Swing « Java Tutorial] -- `DebugGraphicsOptions`を設定して、コンポーネントの描画を逐次表示してデバックする - [[DebugGraphicsを使用してJComponentの描画をデバッグする>Swing/DebugGraphics]] -- `DebugGraphicsOptions`を設定してコンポーネントの描画を逐次遅延してデバックする - [http://www.java2s.com/Tutorial/Java/0240__Swing/DebugGraphics.htm DebugGraphics : DebugGraphics « Swing « Java Tutorial] * コメント [#comment] #comment #comment