001 package org.pbjar.jxlayer.repaint;
002
003 import java.awt.Graphics;
004 import java.awt.event.ActionEvent;
005 import java.awt.event.ActionListener;
006 import java.lang.reflect.Constructor;
007 import java.lang.reflect.Field;
008
009 import javax.swing.JCheckBoxMenuItem;
010 import javax.swing.JFrame;
011 import javax.swing.JMenu;
012 import javax.swing.JMenuBar;
013 import javax.swing.JMenuItem;
014 import javax.swing.JScrollPane;
015 import javax.swing.JTextArea;
016 import javax.swing.RepaintManager;
017 import javax.swing.SwingUtilities;
018
019 import org.pbjar.jxlayer.plaf.ext.transform.TransformRPMFallBack;
020 import org.pbjar.jxlayer.plaf.ext.transform.TransformRPMImpl;
021
022 public class RepaintManagerTest {
023
024 private final Class<RepaintManager> rpmClass = RepaintManager.class;
025
026 private final JMenu optionsMenu = new JMenu("Options");
027
028 private final JCheckBoxMenuItem newRmItem = new JCheckBoxMenuItem(
029 "new RepaintManager Hacked");
030
031 private final JCheckBoxMenuItem newWrappedItem = new JCheckBoxMenuItem(
032 "new WrappedRepaintManager (also hacked)");
033
034 private final JCheckBoxMenuItem doubleBufItem = new JCheckBoxMenuItem(
035 "DoubleBuffering off and on");
036
037 private RepaintManager oldManager;
038
039 private void createGui() {
040
041 optionsMenu.add(newWrappedItem);
042 newWrappedItem.addActionListener(new ActionListener() {
043
044 @Override
045 public void actionPerformed(ActionEvent e) {
046 SwingUtilities.invokeLater(new Runnable() {
047
048 @Override
049 public void run() {
050 oldManager = RepaintManager.currentManager(null);
051 RepaintManager newManager = new TransformRPMFallBack(
052 oldManager);
053 RepaintManager.setCurrentManager(newManager);
054 newWrappedItem.setEnabled(false);
055 }
056 });
057 }
058 });
059
060 optionsMenu.add(newRmItem);
061 newRmItem.addActionListener(new ActionListener() {
062 public void actionPerformed(ActionEvent e) {
063 SwingUtilities.invokeLater(new Runnable() {
064 public void run() {
065 oldManager = RepaintManager.currentManager(null);
066 RepaintManager newManager;
067 try {
068 /*
069 * Ensure that the new RepaintManager has the same
070 * bufferStrategyType as the original.
071 */
072 Field bufferStrategyType = rpmClass
073 .getDeclaredField("bufferStrategyType");
074 bufferStrategyType.setAccessible(true);
075 short strategyType = (Short) bufferStrategyType
076 .get(oldManager);
077 bufferStrategyType.setAccessible(false);
078 switch (strategyType) {
079 case (0):
080 System.out
081 .println("bufferStrategyType: BUFFER_STRATEGY_NOT_SPECIFIED");
082 break;
083 case (1):
084 System.out
085 .println("bufferStrategyType: BUFFER_STRATEGY_SPECIFIED_ON");
086 break;
087 case (2):
088 System.out
089 .println("bufferStrategyType: BUFFER_STRATEGY_SPECIFIED_OFF");
090 break;
091 default:
092 System.out.println("bufferStrategyType: "
093 + strategyType);
094 }
095 /*
096 * Construct a new RepaintManager with its private
097 * constructor and the same bufferStrategyType.
098 */
099 Constructor<RepaintManager> constructor = rpmClass
100 .getDeclaredConstructor(short.class);
101 constructor.setAccessible(true);
102 newManager = constructor.newInstance(strategyType);
103 constructor.setAccessible(false);
104 /*
105 * This is not enough. Now we need to copy the
106 * PaintManager from the original RepaintManager
107 * into the new RepaintManager.
108 */
109 Field paintManager = rpmClass
110 .getDeclaredField("paintManager");
111 paintManager.setAccessible(true);
112 Object paintManagerInstance = paintManager
113 .get(oldManager);
114 System.out
115 .println("PaintManager is of type: "
116 + paintManagerInstance.getClass()
117 .getName());
118 paintManager.set(newManager, paintManagerInstance);
119 paintManager.setAccessible(false);
120 } catch (Throwable t) {
121 t.printStackTrace();
122 newManager = oldManager;
123 }
124
125 RepaintManager.setCurrentManager(newManager);
126 }
127 });
128 newRmItem.setEnabled(false);
129 }
130 });
131
132 optionsMenu.add(doubleBufItem);
133
134 doubleBufItem.addActionListener(new ActionListener() {
135 public void actionPerformed(ActionEvent e) {
136 SwingUtilities.invokeLater(new Runnable() {
137 public void run() {
138 RepaintManager rm = RepaintManager.currentManager(null);
139 rm.setDoubleBufferingEnabled(false);
140 rm.setDoubleBufferingEnabled(true);
141 }
142 });
143
144 doubleBufItem.setEnabled(false);
145 }
146 });
147
148 optionsMenu.addSeparator();
149 JMenuItem clearItem = new JMenuItem("Clear textArea");
150 optionsMenu.add(clearItem);
151
152 JMenuBar bar = new JMenuBar();
153 bar.add(optionsMenu);
154
155 final JTextArea textArea = new JTextArea();
156 textArea.setEditable(false);
157 textArea.setWrapStyleWord(true);
158 textArea.setFont(textArea.getFont().deriveFont(20f));
159
160 clearItem.addActionListener(new ActionListener() {
161 public void actionPerformed(ActionEvent e) {
162 textArea.setText("");
163 }
164 });
165
166 final JFrame frame = new JFrame("RM test") {
167
168 private static final long serialVersionUID = 1L;
169
170 public void paint(Graphics g) {
171 super.paint(g);
172 String newLine = System.currentTimeMillis()
173 + " JFrame.paint()\n";
174 textArea.setText(textArea.getText() + newLine);
175 }
176 };
177
178 frame.add(new JScrollPane(textArea));
179 frame.setJMenuBar(bar);
180 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
181 frame.setSize(300, 300);
182 frame.setLocationRelativeTo(null);
183 frame.setVisible(true);
184 }
185
186 public static void main(String[] args) throws Exception {
187 TransformRPMImpl.hack = true;
188 SwingUtilities.invokeLater(new Runnable() {
189 public void run() {
190 new RepaintManagerTest().createGui();
191 }
192 });
193 }
194 }