Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Glasspane and Saving Graphics

Reply
Thread Tools

Glasspane and Saving Graphics

 
 
Bryan R. Meyer
Guest
Posts: n/a
 
      09-13-2003
Hello All -

I am writing a program that puts HTML in a JEditorPane object which is
then placed in a JFrame object. I have a class (called TestCanvas)
which inherits from Canvas and which I use as the glasspane for the
JFrame. Using the mouse, I can draw lines on the glasspane. This
works beautifully. However, when the JFrame is not in focus or if I
set the glasspane to be invisible and then make it visible again, not
all of the markings that I made on the glasspane remain. Only the
last line I drew shows up when the JFrame is put back in focus or the
glasspane is set to be visible.

The code for the TestCanvas class is below. I suspect I have to save
the Graphics context. Perhaps to an offscreen image? My attempts at
this have been unsuccessful. I'd appreciate any insight. Thanks.
-Bryan


class TestCanvas extends JComponent implements
MouseListener,ActionListener {

boolean firstDraw = true;
JFrame f;
int x=0,y=0;

public TestCanvas(JFrame jfr) {
addMouseListener(this);
f = jfr;
}


public void paint(Graphics g) {
if(!firstDraw) {
g.setColor(Color.red);
g.drawLine(x+5,y+5,x+10,y+10);
System.out.println("x: " + x + " y: " + y);
}
} //End of paint method

public void repaint() {
System.out.println("repaint");
}

public void draw(int x1, int y1) {
x = x1;
y = y1;
paint(this.getGraphics().create());
}


public void actionPerformed(ActionEvent ae) {
this.setVisible(false);
}

public void mousePressed(MouseEvent e) {
}

public void mouseClicked(MouseEvent e) {
Point cPPoint = SwingUtilities.convertPoint(this, e.getPoint(),
f.getContentPane());
Component cmp = SwingUtilities.getDeepestComponentAt(f.getContentP ane(),(int)cPPoint.getX(),(int)cPPoint.getY());
String cmpName = cmp.getName();
if(cmpName==null) {
firstDraw = false;
this.draw(e.getX(),e.getY());
String xx = e.getX() + "";
String yy = e.getY() + "";
//System.out.println("mouse event! " + xx + " " + yy );
}
else {
this.setVisible(false);
}
}

public void mouseReleased(MouseEvent e) {
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}


} //End of HTMLCanvas class
 
Reply With Quote
 
 
 
 
Marco Schmidt
Guest
Posts: n/a
 
      09-13-2003
fup2 comp.lang.java.programmer

Bryan R. Meyer:

>The code for the TestCanvas class is below. I suspect I have to save
>the Graphics context.


A Graphics context does not contain image data. But you can use one to
draw into an image object. Some explanations at
<http://www.geocities.com/marcoschmidt.geo/java-image-faq.html#savecomponent>.

Regards,
Marco
--
Please reply in the newsgroup, not by email!
Java programming tips: http://jiu.sourceforge.net/javatips.html
Other Java pages: http://www.geocities.com/marcoschmidt.geo/java.html
 
Reply With Quote
 
 
 
 
Bryan R. Meyer
Guest
Posts: n/a
 
      09-14-2003
Marco,

Thanks for the help. I understand how to draw to an image, but right
now, that's not my problem. I have somewhat of a feel for what is
happening though. When I set the glasspane to be visible and draw
lines on it, none of the lines are erased. The lines accumulate which
is what I want to happen. When I set the glasspane to be invisible
and then set it back to be visible, the lines all disappear except the
last one drawn. I'm assuming paint(Graphics g) is called again when I
reset the glasspane to be visible. Since the x and y values for the
line are global variables, they are remembered, but the calling of
paint erases the glasspane and only draws the last line (based on the
x and y values).

When I draw multiple lines and the JFrame containing the glasspane
loses focus, the only lines that disappear are those where another
window (such as an application window) has covered those particular
lines. I am really confused as to how to solve the problem. The
invocation of the paint is clearing the graphics. And I have no idea
what is happening with the other problem. Any ideas on workarounds?

Thanks,
Bryan




Marco Schmidt <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> fup2 comp.lang.java.programmer
>
> Bryan R. Meyer:
>
> >The code for the TestCanvas class is below. I suspect I have to save
> >the Graphics context.

>
> A Graphics context does not contain image data. But you can use one to
> draw into an image object. Some explanations at
> <http://www.geocities.com/marcoschmidt.geo/java-image-faq.html#savecomponent>.
>
> Regards,
> Marco

 
Reply With Quote
 
Harald Hein
Guest
Posts: n/a
 
      09-14-2003
"Bryan R. Meyer" wrote:

> I am writing a program that puts HTML in a JEditorPane object
> which is then placed in a JFrame object. I have a class (called
> TestCanvas) which inherits from Canvas and which I use as the
> glasspane for the JFrame.


I didn't read any further, because you indicate that you mix
lightweight (JEditorPane) and heavyweight (Canvas) components. This is
not a good idea. You might want to fix that first (use a JComponent or
JPanel instead of the Canvas).
 
Reply With Quote
 
Steve Claflin
Guest
Posts: n/a
 
      09-14-2003
"Bryan R. Meyer" wrote:
>
> Marco,
>
> Thanks for the help. I understand how to draw to an image, but right
> now, that's not my problem. I have somewhat of a feel for what is
> happening though. When I set the glasspane to be visible and draw
> lines on it, none of the lines are erased. The lines accumulate which
> is what I want to happen. When I set the glasspane to be invisible
> and then set it back to be visible, the lines all disappear except the
> last one drawn. I'm assuming paint(Graphics g) is called again when I
> reset the glasspane to be visible. Since the x and y values for the
> line are global variables, they are remembered, but the calling of
> paint erases the glasspane and only draws the last line (based on the
> x and y values).
>
> When I draw multiple lines and the JFrame containing the glasspane
> loses focus, the only lines that disappear are those where another
> window (such as an application window) has covered those particular
> lines. I am really confused as to how to solve the problem. The
> invocation of the paint is clearing the graphics. And I have no idea
> what is happening with the other problem. Any ideas on workarounds?
>
> Thanks,
> Bryan


The first thing that happens when painting is that the area gets its
background color painted (technically it is not erased, but if something
covered the area, well, the background needs to get put back, too).
Then your commands are executed. But the background color effectively
wipes everything out. Then your paint instructions get called, which
only draw one line. There are a few ways to solve this. One would be
to create something like a Vector and save every line's info; then at
paint time go back and redraw them all. Another would be to create an
offscreen image, draw to that first, then just copy that to the onscreen
image. The offscreen image will accumulate your lines.

Here's some code EXCERPTS from an example that draws boxes -- I've never
tried it on a glass pane, though. As a side note, this example is not
robust, because it doesn't handle things like the frame being resized.

public class Painter {

int x, y, w, h;
Graphics g, gImage;
Image i;
PaintArea pa = new PaintArea();

//in constructor or other initializing method:

g = pa.getGraphics();
i = pa.createImage(pa.getBounds().width, pa.getBounds().height); //
resizing problems arise here
gImage = i.getGraphics();

//the painted component class (which I did as an inner class):

private class PaintArea extends Panel
implements ImageObserver {
public void paint(Graphics g) {

gImage.setColor(c);
gImage.fillRect(x, y, w, h);
g.drawImage(i, 0, 0, this);
}
}
}


--
Steve
--
http://www.steveclaflin.com
 
Reply With Quote
 
Bryan R. Meyer
Guest
Posts: n/a
 
      09-15-2003
Steve and Harald,

Thanks for the information. I do have one more question to ask. I am
now able to accumulate my lines in the offscreen image. I was able to
follow your example Steve and get it to work with the glasspane. My
new problem is two-fold: a) the offscreen image background is gray and
b) the color of my lines can not be set accordingly. If you look at
my code below, I've attempted to set the color of the lines to be red
in the paint(Graphics g) method, but instead they always show up as
the color black. Any ideas as to why?

I suspect that to make the offscreen image transparent (like the
glasspane itself) that I have to mess with the alpha values of the
pixels. This seems rather expensive, but I've found no other
solutions to make the background transparent. Is there a "cheap" way
to do this? As always, thanks for the help.

-Bryan


class TestCanvas extends JComponent implements
MouseListener,ActionListener,ImageObserver {

boolean firstDraw = true;
JFrame f;
int x=0,y=0;
Image img;

public TestCanvas(JFrame jfr) {
addMouseListener(this);
f = jfr;
}


public void addNotify() {
super.addNotify();
img = createImage(400,400);
}


public void paint(Graphics g) {
if(!firstDraw) {
img.getGraphics().setColor(Color.red);
img.getGraphics().drawLine(x+5,y+5,x+10,y+10);
g.drawImage(img, 0, 0, this);
}
} //End of paint method


public void draw(int x1, int y1) {
x = x1;
y = y1;
paint(this.getGraphics().create());
}


public void actionPerformed(ActionEvent ae) {
this.setVisible(false);
}


public void mousePressed(MouseEvent e) {
}


public void mouseClicked(MouseEvent e) {
Point cPPoint = SwingUtilities.convertPoint(this, e.getPoint(),
f.getContentPane());
Component cmp = SwingUtilities.getDeepestComponentAt(f.getContentP ane(),(int)cPPoint.getX(),(int)cPPoint.getY());
String cmpName = cmp.getName();
if(cmpName==null) {
firstDraw = false;
this.draw(e.getX(),e.getY());
}
else {
this.setVisible(false);
}
}


public void mouseReleased(MouseEvent e) {
}


public void mouseEntered(MouseEvent e) {
}


public void mouseExited(MouseEvent e) {
}

} //End of TestCanvas class
 
Reply With Quote
 
Bryan R. Meyer
Guest
Posts: n/a
 
      09-15-2003
Alright, I figured out one problem and thought I would share. I can't
do img.getGraphics().setColor(Color.red). I have to first get the
image graphics then set the color like so:

Image img = createImage(400,400);
Graphics imgG = img.getGraphics();
imgG.setColor(Color.red);

The problem with the transparent background remains. Anyone have any
suggestions that would minimize the use of resources (i.e. I DON'T
want to adjust the alpha values of all the background pixels.) and
enable the offscreen image background to be transparent?

Thanks,
Bryan
 
Reply With Quote
 
Steve Claflin
Guest
Posts: n/a
 
      09-15-2003
"Bryan R. Meyer" wrote:
>
> Alright, I figured out one problem and thought I would share. I can't
> do img.getGraphics().setColor(Color.red). I have to first get the
> image graphics then set the color like so:
>
> Image img = createImage(400,400);
> Graphics imgG = img.getGraphics();
> imgG.setColor(Color.red);
>
> The problem with the transparent background remains. Anyone have any
> suggestions that would minimize the use of resources (i.e. I DON'T
> want to adjust the alpha values of all the background pixels.) and
> enable the offscreen image background to be transparent?
>
> Thanks,
> Bryan


Yeah, I forgot about the glass pane issue. You need to create a
BufferedImage instead of an Image, and use Graphics2D instead of
Graphics, which you can do with:

Graphics2D gImage2d;
BufferedImage bi;

then instead of createImage(400,400); and imgG.getGraphics():

bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
gImage2d = bi.createGraphics();
gImage2d.setColor(new Color(0, 0, 0, 0)); // the last 0 is the alpha
(opacity)
gImage2d.fillRect(0, 0, width, height);

then to draw it:

gImage2d.setColor(Color.red);
gImage2d.drawLine(x1, y1, x2, y2);
g.drawImage(bi, 0, 0, this);


--
Steve
--
http://www.steveclaflin.com
 
Reply With Quote
 
Bryan R. Meyer
Guest
Posts: n/a
 
      09-15-2003
Problem solved.

You can use the GraphicsConfiguration class to make a transparent
image using the createCompatibleImage method. It works great. Thanks
guys for all your help!

Bryan
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Intel HD Graphics 3000 and Intel HD Graphics 2000 Review Ian Front Page News 0 02-24-2011 03:07 PM
Moving objects on GlassPane ignores setLocation() Icarus Java 5 08-03-2008 03:51 PM
Gizmodo: NVIDIA Ships 128-Core Graphics Cards for High-End Film Editors Graphics Pros Silverstrand Front Page News 0 03-05-2007 03:32 PM
Intel Graphics Media Accelerator 900 Graphics Harvey Gratt Computer Support 3 10-09-2005 02:40 AM
Using transparent layer for data input (glassPane?) over another layer Wolfgang Java 1 05-01-2004 03:09 AM



Advertisments