Re: Copying the View of a JPanel
On Jul 2, 6:19 pm, Knute Johnson <nos...@rabbitbrush.frazmtn.com>
wrote:
X wrote:
I have a JPanel that a user can edit and add drawings and Swing
components to, and I want to create a second JPanel that shows the
same thing as what's on the first JPanel. Does anyone know how to best
accomplish this?
My current implementation consists of calling the first JPanel's
paint() method with the second JPanel's Graphics context. This works
fine until the first Swing component is added to the screen. The
second JPanel shows everything but then "freezes" after a Swing
component is added to the first JPanel. Does anyone know what might be
wrong, or does anyone have an alternate suggestion as to how I can
have this second JPanel copy the view from the first JPanel?
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.
In any case I took a different tact, I copy the data from the first
component with a Robot and then draw it on the second. This works
pretty good but if you put something over the first panel such as
another window, that's what shows up in the second panel. Also I just
refresh the second panel every 100ms. You could capture events on the
first window and trigger a repaint then as well.
This was an interesting question but I am curious as to what the purpose
of it is. Are you trying to make some sort of whiteboard connected
across the net?
Anyway, here is my implementation.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class test extends JPanel implements Runnable {
JComponent c;
Robot robot;
public test(JComponent c) {
this.c = c;
try {
robot = new Robot();
} catch (AWTException awte) {
awte.printStackTrace();
}
}
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) { }
repaint();
}
}
public void paint(Graphics g) {
Point p = c.getLocationOnScreen();
Rectangle r = new Rectangle(p,c.getSize());
BufferedImage bi = robot.createScreenCapture(r);
g.drawImage(bi,0,0,null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT=
_ON_CLOSE);
f.setLayout(new FlowLayout());
final JPanel p = new JPanel();
p.setPreferredSize(new Dimension(400,3=
00));
p.setBackground(new Color(0,0,255,40))=
;
JButton b = new JButton("Add Compone=
nt");
b.addActionListener(new ActionListener=
() {
public void actionPerformed(Ac=
tionEvent ae) {
JLabel l = new JLabe=
l("A JLabel");
p.add(l);
p.invalidate();
f.validate();
f.repaint();
}
});
p.add(b);
f.add(p);
test t = new test(p);
t.setPreferredSize(new Dimension(400,3=
00));
f.add(t);
f.pack();
f.setVisible(true);
new Thread(t).start();
}
});
}
}
--
Knute Johnson
email s/nospam/knute2008/
--
Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
------->>>>>>http://www.NewsDemon.com<<<<<<------
Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
Thanks; your implementation works very well. I actually figured out my
problem, though; I learned that my implementation is no longer buggy
if I make sure to grab a fresh graphics context every time I want to
repaint the mirrored JPanel.
Sorry that I don't have any short code to illustrate, but I basically
just grab a graphics context from the mirrored JPanel and call the
original JPanel's paint() method, passing in that graphics context.
The purpose was to create a JPanel whose view can be altered (i.e.,
through affine transformations) while having the original JPanel in
view and intact. I also found out that drawing to a BufferedImage and
having the mirrored JPanel draw that image works just as well.