Problem Centering Canvas on JFrame

Hello Guys,

Hope you can help me out on this one…

My code is here… http://pastebin.java-gaming.org/54a6b1d441c

The problem is that the canvas or JPanel (not sure which) isnt centered in the frame. It seems to start at the top left (0,0) but ends 10 - 20 pixels before the end of the frame. Is there any way i can center it or make it fill the whole frame?

Cheers, Lucas

Not sure if this is a good fix, and I never really used JPanel, but when I did, I’d pull the actual frame back, but leave the canvas as the same size. Like:

JPanel.Display(800x600)
Canvas.Size(810x610)

Something along those lines.

Its is working fine

You are only rendering a 100x100 square so it looks all wrong but if you were to up the size you will see it.

i dont mean the square… but if you run that code and move the square to the bottom right you see what i mean

Cheers

You explicitly remove the panel’s layout manager.
But with ignored repaint the built in layout stuff probably doesn’t work anyway.

I am unsure as to what you mean could you please give me an example

This

panel.setLayout(null);

removes the layout manager from panel. Thus, child components are not automatically positioned.

So, this

panel.add(canvas, BorderLayout.CENTER);

has no effect.

But even if you keep the layout manager, calling

canvas.setIgnoreRepaint(true);

prevents the layout system to be invoked at all (as far as I remember).

The conclusion is, there is no implicit layout managing without further manual steps if active rendering is used.

So, how can this be done, all i want is to be able to paint everywhere and such. Have you run that code and seen what i mean?

it just isnt drawing to the bottom right corner…

Screenshots:

Draws to top left fine:

But not to bottom right:

Help appreciated,

Lucas

Set the same values for the size, preferred size, minimum size, and maximum size on the Canvas, then call JFrame.pack()

There, FTFY. :slight_smile:

I did that… (updated method below) but still same problem. Any ideas.

 public Game(){		
	  Dimension size = new Dimension(WIDTH, HEIGHT);

      frame = new JFrame(NAME);
      JPanel panel = (JPanel) frame.getContentPane();
      panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
      panel.setLayout(null);
      panel.setFocusable(true);
      canvas = new Canvas();
      canvas.setBounds(0, 0, WIDTH, HEIGHT);
      canvas.setIgnoreRepaint(true);     
      panel.add(canvas, BorderLayout.CENTER);
      
      canvas.setSize(size);
      canvas.setPreferredSize(size);
      canvas.setMinimumSize(size);
      canvas.setMaximumSize(size);
      
      
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setResizable(false);
      frame.setVisible(true);      
      
      
      canvas.createBufferStrategy(2);
      bufferStrategy = canvas.getBufferStrategy();     
      canvas.requestFocus();

      canvas.addKeyListener(new KeyListener() {					//KEYLISTENER
	        public void keyPressed(KeyEvent e) {
				if(e.getKeyCode() == KeyEvent.VK_UP){
					Game.up = true;
				}
				if(e.getKeyCode() == KeyEvent.VK_DOWN){
					Game.down = true;
				}
				if(e.getKeyCode() == KeyEvent.VK_LEFT){
					Game.left = true;
				}
				if(e.getKeyCode() == KeyEvent.VK_RIGHT){
					Game.right = true;
				}
	        }

	        public void keyReleased(KeyEvent e) {
	        	if(e.getKeyCode() == KeyEvent.VK_UP){
					Game.up = false;
				}
				if(e.getKeyCode() == KeyEvent.VK_DOWN){
					Game.down = false;
				}
				if(e.getKeyCode() == KeyEvent.VK_LEFT){
					Game.left = false;
				}
				if(e.getKeyCode() == KeyEvent.VK_RIGHT){
					Game.right = false;
				}
	        	
	        }
			public void keyTyped(KeyEvent arg0) {
			}
	      });
	
}

Lucas

Actually I read from another thread that on some occasions if you don’t set the preferred size and the size, it won’t work :S

Try this:

frame.setUndecorated(true);

You need to consider the decoration inset stuff and adjust draw positions.

Don’t believe everything you read.

Anyway, there are no LayoutManagers to do the vertical alignment you want. FlowLayout can do the horizontal alignment, but obviously that’s not enough.

You can either write your own LayoutManager, or calculate the coordinates of the component yourself:

int x = (panel.getWidth() - canvas.getWidth()) / 2;
int y = (panel.getHeight() - canvas.getHeight()) / 2;

You must update these coordinates everytime the parent (panel) is resized.

What if i still want the title bar?

What would i do with the x, y coords?

panel.setLayout(new LayoutManager() {
   public void layoutContainer(Container parent) {
      Component child = parent.getComponents()[0];
      Dimension prefSize = child.getPreferredSize();

      int x = (parent.getWidth() - prefSize.width) / 2;
      int y = (parent.getHeight() - prefSize.height) / 2;
      child.setBounds(x, y, prefSize.width, prefSize.height);
   }

   public Dimension minimumLayoutSize(Container parent) {
      return this.preferredLayoutSize(parent);
   }

   public Dimension preferredLayoutSize(Container parent) {
      return parent.getPreferredSize();
   }

   // AFAIK you can leave the add/remove methods of LayoutManager empty, in this specific case.

   public void addLayoutComponent(String name, Component comp) {}
   public void removeLayoutComponent(Component comp) {}
});
panel.setPreferredSize(new Dimension(w, h));

Thank you very much Riven and 65K, ra4king, SkyAphid, StumpyStrust

Works!!!

hmm … I’m using


frame.setLayout(new GridBagLayout());
frame.add(canvas);

Does that not do what the OP is looking for?

Incidentally, that does fail to work in FSEM on Windows with the D3D pipeline enabled - no idea why, and as I’m either using software rendering or LWJGL I switched D3D off.

I’ve always considered GridBagLayout a crime against usability, so I’ve been avoiding it. Apparently it solves this case in a one-liner.

Yeah that works i think ill go with that… Saves space :stuck_out_tongue:

Thanks