Results 1 to 7 of 7
  1. #1
    typedef is offline Member
    Join Date
    Feb 2014
    Posts
    52
    Rep Power
    0

    Default Understanding the extra pixels?

    Hello everyone. I have a small problem that I've been going back and forth about for quite a while. I was told that setting a JPanel's preferred size would set in its size when a JFrame packs. That is, if JFrame contains only JPanel that it will size its client area to the preferred size of JPanel. I don't understand then why in my code I have to add a mysterious 10 pixels in order to move a dot around a JPanel. Could someone please explain where these extra 10 pixels are coming from?

    The code in the move method checks to make sure the x and y components of the dot do not overstep the size of the JPanel. It does this by making sure it doesn't go lower than 0 in each direction (top left corner) and past (400 - dot width, 300 - dot height) which is the bottom left corner. Of course, I'm having to add 10 pixels to both of those last dimensions.

    My goal is to be able to move a dot (and shapes later on) around a screen to each corner. More specifically I want it to touch the very edge of the JFrame/viewable area (client area? the stuff that doesn't contain the borders).

    Here is my code, its a bit lengthier than I should post but most of it is irrelevant (although a necessary skim) aside from the setting of the preferredSize, paint method, and move method:

    Java Code:
    public class Circle
    {
    	private int dx;
    	private int dy;
    	private int x;
    	private int y;
    	
    	public Circle()
    	{
    		x = 40;
    		y = 60;
    	}
    	
    	public void move()
    	{
    		if (x + dx >= 0 && x + dx <= 400 + 30)
    			x += dx;
    		
    		if (y + dy >= 0 && y + dy <= 300 + 30)
    			y += dy;
    	}
    
    	public int getX()
    	{
    		return x;
    	}
    
    	public int getY()
    	{
    		return y;
    	}
    	
    	public void keyPressed(KeyEvent e)
    	{
    		int key = e.getKeyCode();
    		
    		if (key == KeyEvent.VK_LEFT)
    			dx = -1;
    		
    		if (key == KeyEvent.VK_RIGHT)
    			dx = 1;
    		
    		if (key == KeyEvent.VK_UP)
    			dy = -1;
    		
    		if (key == KeyEvent.VK_DOWN)
    			dy = 1;
    	}
    	
    	public void keyReleased(KeyEvent e)
    	{
    		int key = e.getKeyCode();
    
    		if (key == KeyEvent.VK_LEFT)
    			dx = 0;
    		
    		if (key == KeyEvent.VK_RIGHT)
    			dx = 0;
    		
    		if (key == KeyEvent.VK_UP)
    			dy = 0;
    		
    		if (key == KeyEvent.VK_DOWN)
    			dy = 0;
    	}
    }
    Java Code:
    public class Sandbox extends JPanel
    {
    	private Timer timer;
    	private Circle circle;
    	
    	public Sandbox()
    	{
    		circle = new Circle();
    		setPreferredSize(new Dimension(400, 300));
    		
    		setFocusable(true);
    		setBackground(Color.BLACK);
    		setDoubleBuffered(true);
    		
    		addKeyListener(new KeyAdapter()
    			{
    				public void keyReleased(KeyEvent e)
    				{
    					circle.keyReleased(e);
    				}
    				
    				public void keyPressed(KeyEvent e)
    				{
    					circle.keyPressed(e);
    				}
    			});
    		
    		timer = new Timer(5, new ActionListener()
    			{
    				public void actionPerformed(ActionEvent e)
    				{
    					circle.move();
    					repaint();
    				}
    			});
    		timer.start();
    	}
    	
    	public void paint(Graphics g)
    	{
    		super.paint(g);
    		
    		g.setColor(Color.WHITE);
    		g.fillOval(circle.getX(), circle.getY(), 40, 40);
    		
    		Toolkit.getDefaultToolkit().sync();
    		g.dispose();
    	}
    	
    	public static void main(String[] args)
    	{
    		JFrame frame = new JFrame();
    		Sandbox s = new Sandbox();
    		frame.add(s);
    		
    		frame.pack();
    		System.out.println(frame.getSize());
    		frame.setLocationRelativeTo(null);
    		frame.setTitle("Phy Sandbox");
    		frame.setResizable(false);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setVisible(true);
    	}
    }
    Thank you for your time.

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,534
    Rep Power
    5

    Default Re: Understanding the extra pixels?

    I am probably the one who told you that. So here is what I noticed. You have the following code:

    Java Code:
    public Circle()    {
            x = 40;
            y = 60;
        }
         
        public void move()
        {
            if (x + dx >= 0 && x + dx <= 400 + 30)
                x += dx;
             
            if (y + dy >= 0 && y + dy <= 300 + 30)
                y += dy;
        }
    To make this what I believe would be correct, you need to change the + 30's to -40's. That way, you only draw the circle if it is at least a circle's width away from the bottom and right borders.

    However, that is not the problem. The problem is that when you do a frame.setResizeable(false), it changes something internally. Try this;

    In your circle class above, set x to 360 and y to 260 (and change the 30's to - 40's). With the resizing set to false, the circle will not be butted up against the bottom and right borders. There will be 10 pixel gap as you described. If you leave resizing to default, the circle is displayed as expected.

    I cannot yet explain this behavior. Perhaps someone else can. In the mean time I am going to do some research.

    Regards,
    Jim
    Last edited by jim829; 05-12-2014 at 02:18 PM.
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  3. #3
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,534
    Rep Power
    5

    Default Re: Understanding the extra pixels?

    Ah. Do the frame.setResizeable(false) before you do the pack(). Still not certain why doing it after the pack causes the problem.

    Edit: I also found this --> http://stackoverflow.com/questions/1...dow-size-swing

    Also, regarding your program in general. Even when you are not moving the object, you are continually calling circle.move() and repaint (after the key is released) every 5 milliseconds. This seems excessive and you may want to employ a boolean to control it.

    In Swing, components are double buffered by default.
    Override paintComponent, not paint.
    Don't dispose of the passed graphics context.

    And if you want make your circle appear smoother, you can cast the Graphics context to Graphics2D and set the RenderingHints to enable anti-aliasing.

    I am not certain how you are benefited by using the Toolkit sync method. I have never used it (didn't even know about it until I read your post).

    Regards,
    Jim
    Last edited by jim829; 05-12-2014 at 03:48 PM.
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  4. #4
    typedef is offline Member
    Join Date
    Feb 2014
    Posts
    52
    Rep Power
    0

    Default Re: Understanding the extra pixels?

    Quote Originally Posted by jim829 View Post
    Ah. Do the frame.setResizeable(false) before you do the pack(). Still not certain why doing it after the pack causes the problem.

    Edit: I also found this --> Java setResizable(false) changes the window size (swing) - Stack Overflow

    Also, regarding your program in general. Even when you are not moving the object, you are continually calling circle.move() and repaint (after the key is released) every 5 milliseconds. This seems excessive and you may want to employ a boolean to control it.

    In Swing, components are double buffered by default.
    Override paintComponent, not paint.
    Don't dispose of the passed graphics context.

    And if you want make your circle appear smoother, you can cast the Graphics context to Graphics2D and set the RenderingHints to enable anti-aliasing.

    I am not certain how you are benefited by using the Toolkit sync method. I have never used it (didn't even know about it until I read your post).

    Regards,
    Jim
    Thank you for your response. At least now the misunderstanding is within how the API works rather than my own code. I also tried to change my paint method to paintComponent and paintComponents but under paintComponent I have smearing of the white dot and under paintComponents I get a black screen. I may be wrong but I have a feeling this is related to the fact that fillOval is not a component so under paintComponent it doesn't repaint cause the filling is not a component and under paintComponents it also doesn't repaint and the method takes precedence over the filling. I'm going to continue to see why but if anyone could lend a hand on this second part I would be greatly appreciated.
    Once again thanks for your help so far Jim.

  5. #5
    typedef is offline Member
    Join Date
    Feb 2014
    Posts
    52
    Rep Power
    0

    Default Re: Understanding the extra pixels?

    Quote Originally Posted by jim829 View Post
    Ah. Do the frame.setResizeable(false) before you do the pack(). Still not certain why doing it after the pack causes the problem.

    Edit: I also found this --> Java setResizable(false) changes the window size (swing) - Stack Overflow

    Also, regarding your program in general. Even when you are not moving the object, you are continually calling circle.move() and repaint (after the key is released) every 5 milliseconds. This seems excessive and you may want to employ a boolean to control it.

    In Swing, components are double buffered by default.
    Override paintComponent, not paint.
    Don't dispose of the passed graphics context.

    And if you want make your circle appear smoother, you can cast the Graphics context to Graphics2D and set the RenderingHints to enable anti-aliasing.

    I am not certain how you are benefited by using the Toolkit sync method. I have never used it (didn't even know about it until I read your post).

    Regards,
    Jim
    Thank you for your response. At least now the misunderstanding is within how the API works rather than my own code. I also tried to change my paint method to paintComponent and paintComponents but under paintComponent I have smearing of the white dot and under paintComponents I get a black screen. I may be wrong but I have a feeling this is related to the fact that fillOval is not a component so under paintComponent it doesn't repaint cause the filling is not a component and under paintComponents it also doesn't repaint and the method takes precedence over the filling. I'm going to continue to see why but if anyone could lend a hand on this second part I would be greatly appreciated.
    Once again thanks for your help so far Jim.

    Note: I forgot to mention this code is tightly based off the code on this site: Java 2D games tutorial

  6. #6
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,534
    Rep Power
    5

    Default Re: Understanding the extra pixels?

    When you changed to paintComponent (not paintComponents) I assume you also did super.paintComponent(g) and not super.paint(g)?

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  7. #7
    typedef is offline Member
    Join Date
    Feb 2014
    Posts
    52
    Rep Power
    0

    Default Re: Understanding the extra pixels?

    Quote Originally Posted by jim829 View Post
    When you changed to paintComponent (not paintComponents) I assume you also did super.paintComponent(g) and not super.paint(g)?

    Regards,
    Jim
    I forgot to include super.paintComoponent() completely. It works just as described. I will also take you up on your other suggestions. Thank you.

Similar Threads

  1. Many-to-many with extra columns
    By voipp in forum Hibernate
    Replies: 6
    Last Post: 03-05-2014, 11:42 AM
  2. Extra functionality?
    By CruelCoin in forum New To Java
    Replies: 3
    Last Post: 12-18-2013, 04:41 PM
  3. Extra Sun Voucher available
    By PriyaK in forum Reviews / Advertising
    Replies: 4
    Last Post: 01-15-2010, 06:41 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
  •