Java Forum / GUI / February 2004
graphics don't paint properly - what could be the reason?
learningjava - 30 Jan 2004 22:35 GMT i have created a class that should display and paint a circle on the position clicked at. but the circle does not stay at that position.
please consider this code as written by a Graphics beginner (me).
here is my code:
***** import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class TestContext extends JPanel implements MouseListener {
public TestContext() { addMouseListener(this); }
Circle circle; //this should draw a circle at the curent mouse coordinates public void mousePressed(MouseEvent e) { circle = new Circle(e.getX(), e.getY(), 50, Color.BLUE); //is this the problem? if i do a repaint instead of //the below 2 lines, nothing happens. Graphics g = getGraphics(); circle.render(g); } public void mouseReleased(MouseEvent e) { }
public void mouseClicked(MouseEvent e) { }
public void mouseDragged(MouseEvent e) { }
public void mouseMoved(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
//circle class that has methods to draw a cricle public class Circle { private int x; private int y; private int radius; private Color color;
public Circle(int x, int y, int radius, Color color) { this.x = x; this.y = y; this.radius = radius; this.color = color; }
public void render(Graphics g) { g.setColor(color); g.fillOval(x - radius, y - radius, radius*2, radius*2); repaint(); }
public void erase(Graphics g) { g.dispose(); } public void setPosition(int x, int y) { this.x = x; this.y = y; } } public static void main(String[] args) { JFrame.setDefaultLookAndFeelDecorated(true);//choose the look and feel JFrame frame = new JFrame();//set top level container TestContext tc = new TestContext(); frame.getContentPane().add(tc, BorderLayout.CENTER);//add component //class to container frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(100,100,500,500); frame.setVisible(true); } }
*******
Thanks in advance,
gk
Ryan Stewart - 31 Jan 2004 00:07 GMT > i have created a class that should display and paint a circle on the position > clicked at. [quoted text clipped - 5 lines] > > ***** *snip code*
> ******* > > Thanks in advance, > > gk Yes, don't consider this as written by a Graphics beginner, because *I* wrote it and *you* have hacked it all to pieces. You should be more careful about claiming ownership of what you didn't create. The code I gave you in comp.lang.java.programmer worked perfectly. You seem to have taken it and moved lines of code around at random. The reason it doesn't work is that you moved my render call to the mousePressed method and my repaint calls to the render method (which is in the wrong class, no less). You've created your own unnecessary graphics context. And for some reason, you added a method that's never used: erase(). Beyond not being used, there is no use for it at all since there's *no need* to create a Graphics object (am I repeating myself?), since your JPanel will provide you one via the paintComponent method which I overrode and you removed entirely. Suffice to say, "your" code is entirely screwed up just now. I suggest going back to the code that I gave you (which I won't post again here) and examing why and how it works. If you have questions, then by all means, ask. If you want, I'll even send you another, heavily commented version to look over. Just think twice about plagiarism next time.
Knute Johnson - 31 Jan 2004 00:20 GMT > i have created a class that should display and paint a circle on the position > clicked at. [quoted text clipped - 90 lines] > > gk gk:
If you see two replies, disregard the first one (fat finger).
You've got a couple of problems. This biggest is that all drawing must be done in the paintComponent() method. I rewrote your code to make it work more or less. I also wrote you a simpler version to better explain how it needs to work. There is some problem with the look and feel. It leaves a tell-tale frame when I try it. Probably needs to have super.paintComponent() called to keep it clean. If you do that though it won't leave the old circles up. To make that work you will need to have a drawing surface separate from the component (eg. BufferedImage). If you want an example using the BufferedImage let me know.
Actually I tried putting the super.paintComponent() in my program and it works fine just no preservation of the old circles.
knute...
import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class TestContext extends JPanel implements MouseListener {
public TestContext() { addMouseListener(this); }
Circle circle; //this should draw a circle at the curent mouse coordinates public void mousePressed(MouseEvent e) { circle = new Circle(e.getX(), e.getY(), 50, Color.BLUE); //is this the problem? if i do a repaint instead of //the below 2 lines, nothing happens. // Graphics g = getGraphics(); // circle.render(g); } public void mouseReleased(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) { }
public void mouseDragged(MouseEvent e) { }
public void mouseMoved(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void paintComponent(Graphics g) { super.paintComponent(g); if (circle != null) circle.render(g); repaint(); } //circle class that has methods to draw a cricle public class Circle { private int x; private int y; private int radius; private Color color;
public Circle(int x, int y, int radius, Color color) { this.x = x; this.y = y; this.radius = radius; this.color = color; }
public void render(Graphics g) { g.setColor(color); g.fillOval(x - radius, y - radius, radius*2, radius*2); // repaint(); }
public void erase(Graphics g) { g.dispose(); }
public void setPosition(int x, int y) { this.x = x; this.y = y; } }
public static void main(String[] args) { JFrame.setDefaultLookAndFeelDecorated(true);//choose the look and feel JFrame frame = new JFrame();//set top level container TestContext tc = new TestContext(); frame.getContentPane().add(tc, BorderLayout.CENTER);//add component //class to container frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(100,100,500,500); frame.setVisible(true); } }
import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class test44 extends JPanel { int x,y;
public test44() { addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent me) { x = me.getX(); y = me.getY(); repaint(); } }); }
public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.fillOval(x-25,y-25,50,50); }
public static void main(String[] args) { test44 p = new test44(); JFrame.setDefaultLookAndFeelDecorated(true); JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(p); f.setSize(320,240); f.show(); } }
 Signature Knute Johnson email s/nospam/knute/ Molon labe...
Ryan Stewart - 31 Jan 2004 01:29 GMT > If you see two replies, disregard the first one (fat finger). > [quoted text clipped - 12 lines] > > knute... *snip code*
The code you gave him (the first one) is practically identical to what I gave him (see thread "getting the graphics context from inside event methods" in comp.lang.java.programmer). He changed it all up and posted it here. I based it somewhat off the code he posted originally. He was trying to make a circle object that would draw itself to the screen when he clicked. That's why I game him the longer version rather than your shorter one.
Knute Johnson - 31 Jan 2004 03:54 GMT >>If you see two replies, disregard the first one (fat finger). >> [quoted text clipped - 22 lines] > clicked. That's why I game him the longer version rather than your shorter > one. Sometimes you give them books and they just eat the covers off.
 Signature Knute Johnson email s/nospam/knute/ Molon labe...
Andrew Thompson - 31 Jan 2004 04:08 GMT "Knute Johnson" ... ...
> > The code you gave him (the first one) is practically identical to what I > > gave him (see thread "getting the graphics context from inside event > > methods" in comp.lang.java.programmer). He changed it all up and posted it > > here. 'changed it all up'? I think 'decimated it' or 'destroyed it' would be the technical term.
> Sometimes you give them books and they just eat the covers off. ROTFL ;-)
-- Andrew Thompson * http://www.PhySci.org/ Open-source software suite * http://www.PhySci.org/codes/ Web & IT Help * http://www.1point1C.org/ Science & Technology
Thomas Weidenfeller - 02 Feb 2004 10:33 GMT > Sometimes you give them books and they just eat the covers off.
:-) Oh yes. I told him not to use getGraphics() in cljp, and guess what he used?
/Thomas
learningjava - 02 Feb 2004 17:56 GMT Thanks, Knute. Now I really understood what I was doing wrong. I also tried to understand why the circles won't stay where they were created.Will probably have to use serialization to get an effect of persistence. Will ask you if I ocome across any problems.
gk
> > i have created a class that should display and paint a circle on the position > > clicked at. [quoted text clipped - 229 lines] > } > } Ryan Stewart - 03 Feb 2004 00:06 GMT > Thanks, Knute. > Now I really understood what I was doing wrong. [quoted text clipped - 4 lines] > > gk What's up with the serialization? You asked about that before. What does it have to do with persistence of graphics?
learningjava - 02 Feb 2004 19:03 GMT Hi Knute, I went through both your examples. test44 is very simple and gave me a better understanding of graphics in java. I'm sticking to using TestContext, and trying to have the circle objects persistent on the panel after the mouse is clicked again. Is this a right approach - using an arraylist, to store each circle in it when it is created, and restore (repaint)each one from the arraylist.
You mentioned BufferedImage, can you please give me an idea how to use it for getting a persistent effect.
thanks,, gk
> > i have created a class that should display and paint a circle on the position > > clicked at. [quoted text clipped - 229 lines] > } > } Ryan Stewart - 03 Feb 2004 00:02 GMT *fixed top post*
> Hi Knute, > I went through both your examples. [quoted text clipped - 10 lines] > thanks,, > gk The arraylist approach is one way to do it. But if you don't need to reference the circle objects after you've drawn them, there's no need for that. You need another surface to draw on that won't change, which you can then copy to your JPanel (or other component). That surface would be a BufferedImage, found in the java.awt.image package. You can create one very simply with one of its constructors: BufferedImage backBuffer = new BufferedImage(int width, int height, int imageType);
The width and height can be gotten from your JPanel (or whatever) like with panel.getWidth() and panel.getHeight(). The third is one of several options. Just use BufferedImage.TYPE_INT_RGB for now. So to create your drawing surface, you'd do something like this: BufferedImage backBuffer = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
Then you can get the graphics context for this image: Graphics bbGraphics = backBuffer.getGraphics();
And then you can draw with the bbGraphics object, and anything you draw on the image will stay drawn. Then (finally) during your repaint you'll copy the contents of the BufferedImage to the panel: g.drawImage(backBuffer, 0, 0, null);
So your final product would look something like this:
import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*;
public class DrawingPanel extends JPanel {
private BufferedImage backBuffer; private Graphics bbGraphics;
public DrawingPanel() { setSize(500, 400); backBuffer = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB); bbGraphics = backBuffer.getGraphics(); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { bbGraphics.fillOval(e.getX(), e.getY(), 100, 100); repaint(); } }); }
public void paintComponent(Graphics g) { g.drawImage(backBuffer, 0, 0, null); }
public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(100,100,500,500); DrawingPanel dp = new DrawingPanel(); frame.getContentPane().add(dp, BorderLayout.CENTER); frame.getContentPane().add( new JLabel("You can put something else down here."), BorderLayout.SOUTH); frame.setVisible(true); } }
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|