Re: Copying the View of a JPanel
On 2008-07-03 01:19 +0100, Knute Johnson allegedly wrote:
I tried to write a program to emulate yours but I couldn't do it. I
would be really curious to see your code if you have an SSCCE.
For the sheer fun of it...
<sscce>
package scratch;
import java.applet.Applet;
import java.awt.geom.AffineTransform;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.plaf.*;
public class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
ChainingRepaintManager crm = new
ChainingRepaintManager( RepaintManager.currentManager(null) );
RepaintManager.setCurrentManager(crm);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel c = new JPanel(new GridLayout(2, 1));
c.add(new JCheckBox("Byte me!"));
c.add(new JCheckBox("Byte me too!"));
f.getContentPane().add(c, BorderLayout.WEST);
f.getContentPane().add( new MirrorComponent(c) ,
BorderLayout.EAST );
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private static class MirrorComponent
extends JComponent
{
public MirrorComponent(JComponent mirrored){
super();
setUI( new MirrorUI(mirrored) );
}
}
private static class MirrorUI
extends ComponentUI
{
private JComponent
mirroredComponent
;
private ComponentListener
compListener
;
private AffineTransform
transform
;
private final Dimension
lastSize = new Dimension()
;
private PaintChain
paintChain
;
public MirrorUI(JComponent mirrored){
mirroredComponent = mirrored;
}
public void paint(Graphics g, JComponent c) {
if( transform == null ){
updateTransform();
}
Image i =
RepaintManager.currentManager(mirroredComponent).getOffscreenBuffer(c,
c.getWidth(), c.getHeight());
Graphics scratch = i.getGraphics();
mirroredComponent.paint( scratch );
scratch.dispose();
Graphics2D g2d = (Graphics2D) g;
AffineTransform old = g2d.getTransform();
g2d.transform( transform );
g2d.drawImage(i, 0, 0, null);
g2d.setTransform( old );
}
public void uninstallUI(JComponent c) {
mirroredComponent.removeComponentListener( compListener );
RepaintManager rm = RepaintManager.currentManager(c);
if( paintChain != null && rm instanceof
ChainingRepaintManager ){
((ChainingRepaintManager)rm).removePaintChain(
paintChain );
}
}
public void installUI(JComponent c) {
mirroredComponent.addComponentListener(
createComponentListener(c) );
RepaintManager rm = RepaintManager.currentManager(c);
if( rm instanceof ChainingRepaintManager ){
paintChain = new PaintChain(mirroredComponent, c);
((ChainingRepaintManager)rm).addPaintChain( paintChain );
}
}
public Dimension getPreferredSize(JComponent c) {
return mirroredComponent.getPreferredSize();
}
public Dimension getMinimumSize(JComponent c) {
return mirroredComponent.getMinimumSize();
}
public Dimension getMaximumSize(JComponent c) {
return mirroredComponent.getMaximumSize();
}
private ComponentListener createComponentListener(JComponent c){
return compListener = new _ComponentListener(c);
}
private void updateTransform(){
Dimension d = mirroredComponent.getSize();
if( transform == null || ! d.equals(lastSize) ){
lastSize.setSize(d);
transform = new AffineTransform(-1, 0, 0, 1, d.width, 0);
}
}
private class _ComponentListener
extends ComponentAdapter
{
private final JComponent component;
public _ComponentListener(JComponent c){
super();
component = c;
}
public void componentHidden(ComponentEvent e) {
component.setVisible(false);
}
public void componentShown(ComponentEvent e) {
component.setVisible(true);
}
public void componentResized(ComponentEvent e) {
updateTransform();
}
}
}
private static class PaintChain {
protected final Component
sourceComponent,
targetComponent
;
public PaintChain(Component source, Component target){
sourceComponent = source;
targetComponent = target;
if( source == null || target == null ){
throw new IllegalArgumentException(new
NullPointerException());
}
if( source == target ){
throw new IllegalArgumentException("source equals target");
}
}
public Component getSourceComponent() {
return sourceComponent;
}
public Component getTargetComponent() {
return targetComponent;
}
public int hashCode(){
return sourceComponent.hashCode() ^ targetComponent.hashCode();
}
public boolean equals(Object o){
return o != null && (o == this || o instanceof PaintChain
&& o.hashCode() == this.hashCode());
}
}
private static class ChainingRepaintManager
extends RepaintManager
{
protected final RepaintManager
delegate
;
private Set<PaintChain>
chains = new HashSet<PaintChain>()
;
public ChainingRepaintManager(RepaintManager delegate){
this.delegate = delegate;
}
public boolean addPaintChain(PaintChain pc){
return chains.add(pc);
}
public boolean removePaintChain(PaintChain pc){
return chains.remove(pc);
}
public String toString() {
return delegate.toString();
}
public void validateInvalidComponents() {
delegate.validateInvalidComponents();
}
public void paintDirtyRegions() {
delegate.paintDirtyRegions();
}
public Dimension getDoubleBufferMaximumSize() {
return delegate.getDoubleBufferMaximumSize();
}
public int hashCode() {
return delegate.hashCode();
}
public boolean isDoubleBufferingEnabled() {
return delegate.isDoubleBufferingEnabled();
}
public void addDirtyRegion(Window window, int x, int y, int w,
int h) {
delegate.addDirtyRegion(window, x, y, w, h);
}
public boolean equals(Object obj) {
return delegate.equals(obj);
}
public Image getOffscreenBuffer(Component c, int proposedWidth,
int proposedHeight) {
return delegate.getOffscreenBuffer(c, proposedWidth,
proposedHeight);
}
public Image getVolatileOffscreenBuffer(Component c, int
proposedWidth, int proposedHeight) {
return delegate.getVolatileOffscreenBuffer(c,
proposedWidth, proposedHeight);
}
public void addDirtyRegion(JComponent c, int x, int y, int w,
int h) {
delegate.addDirtyRegion(c, x, y, w, h);
for(JComponent chained: collectChainedAncestors(c)){
delegate.markCompletelyDirty(chained);
}
}
public void setDoubleBufferingEnabled(boolean aFlag) {
delegate.setDoubleBufferingEnabled(aFlag);
}
public void addDirtyRegion(Applet applet, int x, int y, int w,
int h) {
delegate.addDirtyRegion(applet, x, y, w, h);
}
public void setDoubleBufferMaximumSize(Dimension d) {
delegate.setDoubleBufferMaximumSize(d);
}
public void removeInvalidComponent(JComponent component) {
delegate.removeInvalidComponent(component);
}
public void addInvalidComponent(JComponent invalidComponent) {
delegate.addInvalidComponent(invalidComponent);
for(JComponent chained:
collectChainedAncestors(invalidComponent)){
delegate.addInvalidComponent(chained);
}
}
public Rectangle getDirtyRegion(JComponent aComponent) {
return delegate.getDirtyRegion(aComponent);
}
public boolean isCompletelyDirty(JComponent aComponent) {
return delegate.isCompletelyDirty(aComponent);
}
public void markCompletelyClean(JComponent aComponent) {
delegate.markCompletelyClean(aComponent);
}
public void markCompletelyDirty(JComponent aComponent) {
delegate.markCompletelyDirty(aComponent);
for(JComponent chained: collectChainedAncestors(aComponent)){
delegate.markCompletelyDirty(chained);
}
}
private Collection<JComponent>
collectChainedAncestors(JComponent comp){
Collection<JComponent> ret = new HashSet<JComponent>();
for(Container c = comp; c instanceof JComponent; c =
c.getParent()){
for(PaintChain pc: chains){
if( pc.getSourceComponent() == c ){
ret.add( (JComponent) pc.getTargetComponent() );
}
}
}
return ret;
}
}
}
</sscce>
--
DF.
to reply privately, change the top-level domain
in the FROM address from "invalid" to "net"