|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
AbstractComponentDecorator.java | 50% | 71.1% | 80% | 68.3% |
|
1 |
package abbot.editor.widgets;
|
|
2 |
|
|
3 |
import java.awt.*;
|
|
4 |
import java.awt.event.*;
|
|
5 |
import javax.swing.*;
|
|
6 |
import java.lang.ref.*;
|
|
7 |
import java.util.*;
|
|
8 |
|
|
9 |
import abbot.Log;
|
|
10 |
|
|
11 |
/** Provide a method for consistently painting over a given component.
|
|
12 |
This implementation uses an invisible, added componenet in order to insert
|
|
13 |
code at the appropriate time in the painting process.
|
|
14 |
*/
|
|
15 |
// cf CellRendererPane
|
|
16 |
public abstract class AbstractComponentDecorator { |
|
17 |
private Container component;
|
|
18 |
private Renderer renderer;
|
|
19 |
private boolean inViewport; |
|
20 |
|
|
21 |
/** Create a decorator for the given component. */
|
|
22 | 5 |
public AbstractComponentDecorator(Container c) {
|
23 | 5 |
if (c instanceof JViewport |
24 |
&& c.getComponentCount() != 0 |
|
25 |
&& c.getComponents()[0] instanceof Container) {
|
|
26 | 0 |
c = (Container)c.getComponents()[0]; |
27 |
// Viewports only support a single child, so instead add to the
|
|
28 |
// child, and use the viewport's graphics to paint any areas
|
|
29 |
// outside the child.
|
|
30 | 0 |
inViewport = true;
|
31 |
} |
|
32 | 5 |
else if (c instanceof RootPaneContainer) { |
33 | 0 |
c = ((RootPaneContainer)c).getLayeredPane(); |
34 |
} |
|
35 | 5 |
else if (c instanceof JRootPane) { |
36 | 0 |
c = ((JRootPane)c).getLayeredPane(); |
37 |
} |
|
38 | 5 |
component = c; |
39 | 5 |
renderer = new Renderer();
|
40 |
// FIXME never add anything to JViewport
|
|
41 | 5 |
component.add(renderer); |
42 | 5 |
component.repaint(); |
43 |
// don't repaint the viewport here, or any custom painting
|
|
44 |
// will be wiped out.
|
|
45 |
} |
|
46 |
|
|
47 | 0 |
protected Container getComponent() { return component; } |
48 |
|
|
49 |
/** Stop decorating. */
|
|
50 | 2 |
public void dispose() { |
51 | 2 |
Runnable action = new Runnable() {
|
52 | 2 |
public void run() { |
53 | 2 |
component.remove(renderer); |
54 | 2 |
component.repaint(); |
55 | 2 |
if (inViewport)
|
56 | 0 |
component.getParent().repaint(); |
57 | 2 |
synchronized(AbstractComponentDecorator.this) { |
58 | 2 |
renderer = null;
|
59 | 2 |
component = null;
|
60 |
} |
|
61 |
} |
|
62 |
}; |
|
63 | 2 |
if (SwingUtilities.isEventDispatchThread()) {
|
64 | 0 |
action.run(); |
65 |
} |
|
66 |
else {
|
|
67 | 2 |
SwingUtilities.invokeLater(action); |
68 |
} |
|
69 |
} |
|
70 |
|
|
71 |
public abstract void paint(Graphics g); |
|
72 |
|
|
73 |
private class Renderer extends JComponent { |
|
74 | 5 |
public Renderer() {
|
75 | 5 |
setOpaque(false);
|
76 |
} |
|
77 | 5 |
public void invalidate() { } |
78 | 9 |
public boolean isVisible() { return true; } |
79 | 0 |
public boolean isShowing() { return true; } |
80 | 6 |
public Rectangle getBounds(Rectangle b) {
|
81 |
// Pretend to have the same bounds as the component
|
|
82 | 6 |
b = component.getBounds(b); |
83 | 6 |
b.x = 0; |
84 | 6 |
b.y = 0; |
85 | 6 |
Log.debug("bounds: " + b);
|
86 | 6 |
return b;
|
87 |
} |
|
88 |
// must use the paint method; paintComponent will not work here
|
|
89 | 6 |
public void paint(Graphics g) { |
90 | 6 |
synchronized(AbstractComponentDecorator.this) { |
91 | 6 |
if (inViewport) {
|
92 | 0 |
Log.debug("painting viewport");
|
93 | 0 |
Graphics g2 = component.getParent().getGraphics(); |
94 | 0 |
AbstractComponentDecorator.this.paint(g2);
|
95 |
} |
|
96 | 6 |
Log.debug("painting component");
|
97 | 6 |
AbstractComponentDecorator.this.paint(g);
|
98 |
} |
|
99 |
// NOTE: see paintComponent from CellRendererPane
|
|
100 |
// setBounds(-width,-height,0,0) to avoid getting any input
|
|
101 |
} |
|
102 |
} |
|
103 |
} |
|
104 |
|
|