Results 1 to 4 of 4
  1. #1
    rhexis is offline Member
    Join Date
    Nov 2011
    Posts
    56
    Rep Power
    0

    Default What am I doing wrong? Shrinking circle leaves a smear.

    Java Code:
    package ntsh;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class MyGUI {
    
    	private MyPanel myPanel;
    	private int height = 50;
    	private int width = 50;
    	private int x = 54;
    	private int y = 225;
    	private int panelWidth;
    	private int center;
    
    	public void go() {
    		JFrame newFrame = new JFrame("MyGui test");
    
    		newFrame.setLayout(new BorderLayout());
    
    		JButton eastButton = new JButton("Increase!");
    		newFrame.add(eastButton, BorderLayout.EAST);
    
    		myPanel = new MyPanel();
    		newFrame.add(myPanel, BorderLayout.CENTER);
    
    		JButton westButton = new JButton("Decrease!");
    		newFrame.add(westButton, BorderLayout.WEST);
    
    		ActionListener doInc = new Increaser();
    		eastButton.addActionListener(doInc);
    
    		ActionListener doDec = new Decreaser();
    		westButton.addActionListener(doDec);
    
    		newFrame.add(myPanel, BorderLayout.CENTER);
    
    		newFrame.getContentPane().setPreferredSize(new Dimension(500, 500));
    		newFrame.pack();
    
    		newFrame.setVisible(true);
    		newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	}
    
    	private class MyPanel extends JPanel {
    		public void paintComponent(Graphics g) {
    
    			super.paintComponent(g);
    
    			panelWidth = getWidth();
    			g.setColor(Color.white);
    			g.fillRect(0, 0, getWidth(), getHeight());
    
    			g.setColor(Color.blue);
    			g.fillOval(x, y, width, height);
    
    		}
    	}
    
    	private class Increaser implements ActionListener {
    
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			if (width <= panelWidth + 1) {
    				height += 2;
    				width += 2;
    				x = panelWidth / 2 - findCenter(height);
    				y = 500 / 2 - findCenter(height);
    				myPanel.repaint(x, y, width, height);
    			} else {
    			}
    		}
    	}
    
    	private class Decreaser implements ActionListener {
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			if (width <= panelWidth + 1) {
    				height -= 2;
    				width -= 2;
    				System.out.println("Shrinked: " + height);
    				System.out.println("Shrinked: " + width);
    				x = panelWidth / 2 - findCenter(height);
    				y = 500 / 2 - findCenter(height);
    				System.out.println("Shrinked Centre x: " + x);
    				System.out.println("Shrinked Centre y: " + y);
    				myPanel.repaint(x, y, width, height);
    			} else {
    			}
    		}
    	}
    
    	public int findCenter(int sizeOfCircle) {
    		center = sizeOfCircle / 2;
    		return center;
    
    	}
    
    	public static void main(String[] args) {
    		MyGUI gui = new MyGUI();
    		gui.go();
    	}
    }
    The above is my code for a grow and shrink circle. I am stuck. Everything seems fine but when I shrink my circle, it leaves a smear. Something like this.

    What am I doing wrong? Shrinking circle leaves a smear.-smear.png

    I've read up and they asked me to do a g.setColor(Color.white) and fill the panel using g.fillRect(0,0,getWidth(),getHeight()), but it still doesn't work.

    Anyone can enlighten me? I don't need the code, just somewhere else I can look to. Thank you very much!
    Last edited by pbrockway2; 12-08-2011 at 12:31 AM.

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: What am I doing wrong? Shrinking circle leaves a smear.

    I think what you're seeing is a geometrical "rounding" problem with bits of the old circle remaining when you shrink it.

    The suggestion of painting the background (does that do anything in this case?) won't help because the rounding occurs when you say:

    Java Code:
    myPanel.repaint(x, y, width, height);
    x and y may be a *little* too large (say 1 pixel) and width and height a little too small (say 2 pixels). From the look of it, it is the latter pair that are mostly to blame, but the easiest thing would be to tweak all 4. (Or just paint everything with circleDrawPanel.repaint().)

    [Edit] Of course I don't mean you should change the values of those variables: just the values that are passed to the repaint() method as that determines what area gets updated.
    Last edited by pbrockway2; 12-08-2011 at 12:31 AM.

  3. #3
    rhexis is offline Member
    Join Date
    Nov 2011
    Posts
    56
    Rep Power
    0

    Default Re: What am I doing wrong? Shrinking circle leaves a smear.

    Hi pbrockway2,

    Thanks for the quick reply. My goodness. I just tried a myPanel.repaint() and it worked like a charm. Could you explain this to me as to why it worked while my previous code didn't? Thank you!

    Oh and would it be possible to allow me to edit my post above? It's the same reason as my previous thread. One is able to find this post if they key in the class's name. I would like to edit the class name as well as some of my methods so if any of my classmates stumble onto this post, they would not be able to copy it. Thank you!
    Last edited by pbrockway2; 12-08-2011 at 12:32 AM.

  4. #4
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: What am I doing wrong? Shrinking circle leaves a smear.

    The difference is in the behaviour of the two repaint() methods. As always the API docs are a good source of information:

    repaint(): "Repaints this component. If this component is a lightweight component, this method causes a call to this component's paint method as soon as possible. Otherwise, this method causes a call to this component's update method as soon as possible."

    whereas repaint(x,y,width,height): "Repaints the specified rectangle of this component. If this component is a lightweight component..."

    By using the second version you are essentially "cropping" the repaint to a specific rectangle. That's often a good thing because it reduces the amount of work that has to be done, but it is important that the rectangle defined by x/y/width/height actually includes all of the area that has changed.

    As you have found it is not enough to calculate this area mathematically: you also have to take into account that you are working with a whole number of pixels and that, at best, only approximates a real circle. The rules for what pixels actually get painted when you draw, eg, a circle are spelt out in great detail in the documentation, but in practice the easiest thing to do is make the rectangle a little larger than what mathematics would suggest to ensure that the whole changed region is covered. Or, as in this case, just redraw the whole thing.

Similar Threads

  1. recursive directories deletion leaves random files
    By Jovaras in forum New To Java
    Replies: 11
    Last Post: 05-27-2011, 11:29 AM
  2. Why is there no circle?
    By JohnPringle83 in forum New To Java
    Replies: 3
    Last Post: 05-23-2011, 09:07 AM
  3. JPanel shrinking-expanding problem
    By eLancaster in forum New To Java
    Replies: 4
    Last Post: 04-14-2011, 06:48 PM
  4. Replies: 6
    Last Post: 01-31-2010, 02:44 PM
  5. Circle and line
    By c_walker in forum New To Java
    Replies: 1
    Last Post: 01-27-2010, 04:56 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •