Hi - what im trying to do is to create a way of centering an image on a frame no matter what the size of the frame. I have two classes: one called "Picture_Frame.java"; the other "MyImage.java" In the latter I get the image and paint it then call on using the other class; thus adding it to my frame.

When I specify the location of the image in this line:

g2d.drawImage(up, 10, 10, null);

thats all good. But when I do this:

g2d.drawImage(up, ( (frameProperties.getX())/2 ), (frameProperties.getY())/2, null);

I get alot of errors. The complete codes are:

public class myImage extends JPanel 
{
		// Name of image
	    Image up;
	    
	    // The intention of the instance below is to position the picture created in the center of the frame; no matter what the size of the frame
	    Picture_Frame frameProperties = new Picture_Frame();

	    public myImage() 
	    {
	    	// Location of the image
	        ImageIcon ii = new ImageIcon( this.getClass().getResource("up.jpg") );
	        up = ii.getImage();
	    }

	    public void paint(Graphics g) 
	    {
	    	// Paint the image and call it
	    	Graphics2D g2d = (Graphics2D) g;
	    	
	    	// drawImage( image, x position on frame, y position on frame, observer)
	        g2d.drawImage(up, ( (frameProperties.getX())/2 ), (frameProperties.getY())/2, null); 
	    }
}

And the other class is:

import java.awt.Color;
import javax.swing.*;

public class Picture_Frame extends JFrame
{
	final int x = 250;	final int y = 200;
	// Constructor to create the frame
	   public Picture_Frame() 
	   {
		    // Add the image to the frame
	        add( new myImage() );
	        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	        setSize(x, y);
	        setLocationRelativeTo(null);
	        setTitle("Images");
	        setVisible(true);
	        setBackground(Color.RED);
	    }
	   
	    public static void main(String[] args) 
	    {
	        new Picture_Frame();
	    }
	    
	    // Return the x size of the frame
	    public int getX()
	    {
	    	return x;
	    }
	    
	    // Return the y size of the frame
	    public int getY()
	    {
	    	return y;
	    }
}

Whats the problem anyone?

Wait I had a brain wave - is because I am dividing a value of type integer into something which may potential yield an uneven number? For example 7/2 would be 3.5 - and you cannot position a component like that?

Does this mean I should round it up or down in order to centre the image?

Divide an integer by another integer and the result is truncated to int. So 7/2 is 3 exactly.

I am making quite stupid mistakes here >( My bad cheers for pointing that out
I am actually getting a StackOverFlowError

It looks like PictureFrame's constructor creates a new myImage (line 11), and each new myImage creates a new PictureFrame (line 7). Just saw your post - yes = stack overflow!

Edited 6 Years Ago by JamesCherrill: n/a

Perhaps pass the PictureFrame instance to myImage's constructor as a parameter, rather than creating a new one? You will certainly need to do it this way if the user can resize the PictureFrame.

Perhaps pass the PictureFrame instance to myImage's constructor as a parameter, rather than creating a new one? You will certainly need to do it this way if the user can resize the PictureFrame.

Im not sure exactly how I can go about this however regarding the user being able to resize the window: they won't as I will add the

setResizable(false);

Surely Im making this more complicated than it needs to be right? Are there any other methods available that can do this or am I travelling along the right lines?

If you create a JComponent, you could use BorderLayout.CENTER...

Edited 6 Years Ago by coil: n/a

Instead of your getX/getY methods you can use JFrame's getWidth and getHeight, which will always be current. coil's suggestion is another good way to approach this, depending on what else you intend to do later.

If you create a JComponent, you could use BorderLayout.CENTER...

The problem with that is two-fold: 1 - im not using borderlayout therefore I cant use .center & 2 - I am calling the paint method which requires x & y coordinates to position the image.
(Btw Im not trying to be patronising just in case it sounds like I am :P)

I tested the methods I have be getting rid of adding the image to the frame and they all work fine - therefore I think the problem lies in adding the image onto the frame...

Your problem is the infinite loop I described earlier.
I don't know why you are using paint(...), but it is easy to read your image into an ImageIcon, add that to a JLabel, and use borderlayout to center the JLabel, all without the need to do special paint code.
ps: I'll be offline now till tomorrow (C.E.T.)

You can mix and match layouts, Katana, I believe. That is, it is possible to have some components with FlowLayout and others with BorderLayout.

And I don't really understand your second problem...if you create a class extending JComponent, you will still be drawing your Image.

Hope this helps!

Cheers all for help but I think I got it sorted out...kinda - yeah coil I know you can mix and match but my java has been rusty recently and I need to begin again at the basics :P

So I decided that (as pointed out by JamesCherrill) the program was executing an infinite loop because each was calling the other in their constructors therefore I decided that I would have to scrap the constructor type method and use something else.

I still have the two classes but the constructors have been eliminated. I have got the image to centre for say a frame of x =500 & y =500. However when you change these values it gets complicated as each requires a different equation to centre it - which I don't want to think about now lol.

Here's the code for both:

import javax.swing.*;
import java.awt.*;

public class Frame_Image extends JFrame
{
	final static int x = 500;	final static int y = 500;
	
	private static void createShowGUI() 
	{
		JFrame frame = new JFrame("Frame");
		frame.setSize(x,y);
		
		frame.add(new new_Image() );
		frame.setVisible(true);
		frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);
		// frame.setResizable(false);
	}
	
	public int getX()
	{
		int halfX = (x/10); //-120;
		return halfX;
	}
	
	public int getY()
	{
		int halfY = (y/10); //-120;
		return halfY;
	}
	
	public static void main(String [] args)
	{
		createShowGUI();
	}
}

And the second class:

import java.awt.*;
import javax.swing.*;

public class new_Image extends JPanel
{
	private Image up;
	private Frame_Image location = new Frame_Image();
	public int x, y;
	
	public new_Image() 
	{
		
		   
		    	ImageIcon ii = new ImageIcon(this.getClass().getResource("up.jpg"));
		        up = ii.getImage();
		        
		        x = ( location.getX() );
		        y = ( location.getY() );
		        
		        setPreferredSize(new Dimension(20,20) );
	}
		    
		    public void paint(Graphics g) {

		        Graphics2D g2d = (Graphics2D) g;
		        g2d.drawImage(up, x, y, null); 			// Determines where to draw the image		        
		    }
}

Thanks for help all :P

Cheers all for your help - the problem was the infinity loop caused by the two classes calling each other over & over via their constructors. So i decided to go a different direction - it may not totally centre the image every time but it does what I need it to at this point.

Here's the code:

package Images;

import javax.swing.*;
import java.awt.*;

public class Frame_Image extends JFrame
{
	final static int x = 500;	final static int y = 500;
	
	private static void createShowGUI() 
	{
		JFrame frame = new JFrame("Frame");
		frame.setSize(x,y);
		
		frame.add(new new_Image() );
		frame.setVisible(true);
		frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);
		// frame.setResizable(false);
	}
	
	public int getX()
	{
		int halfX = (x/10); //-120;
		return halfX;
	}
	
	public int getY()
	{
		int halfY = (y/10); //-120;
		return halfY;
	}
	
	public static void main(String [] args)
	{
		createShowGUI();
	}
}

And the other class:

package Images;

import java.awt.*;
import javax.swing.*;

public class new_Image extends JPanel
{
	private Image up;
	private Frame_Image location = new Frame_Image();
	public int x, y;
	
	public new_Image() 
	{
		
		   
		    	ImageIcon ii = new ImageIcon(this.getClass().getResource("up.jpg"));
		        up = ii.getImage();
		        
		        x = ( location.getX() );
		        y = ( location.getY() );
		        
		        setPreferredSize(new Dimension(20,20) );
	}
		    
		    public void paint(Graphics g) {

		        Graphics2D g2d = (Graphics2D) g;
		        g2d.drawImage(up, x, y, null); 			// Determines where to draw the image		        
		    }
}

Cheers all for help :D

This question has already been answered. Start a new discussion instead.