14 Replies - 341 Views - Last Post: 05 April 2013 - 02:48 PM Rate Topic: -----

#1 durby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 24-October 12

JPanel not displaying properly

Posted 04 April 2013 - 02:32 PM

So I'm new to swing and wanted to try a small game.

MainWindow
package window;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;

import backend.BackendAPI;

@SuppressWarnings("serial")
public class MainWindow extends JFrame {
	public static BackendAPI backend = new BackendAPI();

	private GameBoard board = new GameBoard();
	private List list = new List(this.board);
	private Display main = new Display(this.board);

	public MainWindow() {
		super();
		this.setPreferredSize(new Dimension(600, 400));
		getContentPane().setLayout(new GridBagLayout());
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.fill = GridBagConstraints.BOTH;
		constraints.weighty = 1;

		list.setBackground(Color.GREEN);
		getContentPane().add(list, constraints);

		constraints.gridx = 1;
		constraints.weightx = 1;
		getContentPane().add(board, constraints);

		constraints.gridx = 2;
		constraints.weightx = 0;
		main.setBackground(Color.BLUE);
		getContentPane().add(main, constraints);

		setVisible(true);
		pack();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		@SuppressWarnings("unused")
		MainWindow m = new MainWindow();
	}
}



If I instead of adding the board on line 33 just add an ordinary JPanel it works as it should so I imagine the problem is in the GameBoard class:

package window;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JPanel;

import labyrinth.Level;
import labyrinth.Node;
import labyrinth.NodeFloor;
import labyrinth.NodeGoal;
import labyrinth.NodeWall;
import labyrinth.Player;
import values.Colors;
import values.ElementsEnum;
import action.DrawMapAction;

@SuppressWarnings("serial")
public class GameBoard extends JPanel {
	private ElementsEnum type = ElementsEnum.FLOOR;
	// The x and y size of the game board.
	private int x = 10;
	private int y = 15;
	private JPanel[][] map = new JPanel[x][y];
	private String name = "default";

	public GameBoard() {
		super();
		this.setBackground(Color.DARK_GRAY);
		this.setLayout(new GridBagLayout());
		setupMap();
		drawMap();
		this.addMouseListener(new DrawMapAction(this));
	}

	private void setupMap() {
		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[0].length; j++) {
				map[i][j] = new JPanel();
				map[i][j].setBackground(Colors.floorColor);
			}
		}
	}

	public void drawMap() {
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.weightx = 1;
		constraints.weighty = 1;
		constraints.fill = GridBagConstraints.BOTH;

		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[0].length; j++) {
				constraints.gridx = i;
				constraints.gridy = j;
				this.add(map[i][j], constraints);
			}
		}

		this.updateUI();
	}

	public void loadMap(Level level) {
		Player p = level.getPlayer();
		Node[][] tempMap = level.getMap();

		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[0].length; j++) {
				if (tempMap[i][j] instanceof NodeFloor) {
					if (tempMap[i][j].hasBox()) {
						this.map[i][j].setBackground(Colors.boxColor);
					} else {
						this.map[i][j].setBackground(Colors.floorColor);
					}
				} else if (tempMap[i][j] instanceof NodeGoal) {
					if (tempMap[i][j].hasBox()) {
						this.map[i][j].setBackground(Colors.boxColor);
					} else {
						this.map[i][j].setBackground(Colors.goalColor);
					}
				} else if (tempMap[i][j] instanceof NodeWall) {
					this.map[i][j].setBackground(Colors.wallColor);
				}
			}
		}

		if (p != null) {
			this.map[p.getX()][p.getY()].setBackground(Colors.playerColor);
		}
	}

	// ------------------------------------
	// ------- Getters and Setters --------
	// ------------------------------------

	public ElementsEnum getType() {
		return type;
	}

	public void setType(ElementsEnum type) {
		this.type = type;
	}

	public JPanel[][] getMap() {
		return map;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}



What I want it to do is to draw a grid on itself. However the grid looks like this:

Posted Image
I'd like the grid to fill the entire middle frame. If I click on it to change a square it updates and fills the frame except for the lower ~10 pixels who don't update.

I've tried to comment the lines 32-33-34 in GameBoard but the result is the same as the image except I now get the gray background.

Any ideas what I've done wrong?

Is This A Good Question/Topic? 0
  • +

Replies To: JPanel not displaying properly

#2 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: JPanel not displaying properly

Posted 04 April 2013 - 05:42 PM

Why is backEndApi static ?
Leave GridBagLayout to GUI Builder
If you write your GUI: FlowLayout, GridLayout, BorderLayout and BoxLayout is all what you need
Was This Post Helpful? 0
  • +
  • -

#3 durby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 24-October 12

Re: JPanel not displaying properly

Posted 05 April 2013 - 04:01 AM

BackendAPI is static so that other classes can access it without having to pass it along all the time.

Changing the layout from GridBagLayout to GridLayout does not solve the problem of the JPanel not painting itself where it's supposed to be.

When I start the program it looks like the image above, when I click on the panel to change the color of one of its boxes then it get's painted filling out the middle as it should. But if I then resize the window it goes back to not filling it out.

Any ideas what I've done wrong?
Was This Post Helpful? 0
  • +
  • -

#4 farrell2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 797
  • View blog
  • Posts: 2,422
  • Joined: 29-July 11

Re: JPanel not displaying properly

Posted 05 April 2013 - 04:42 AM

I have to agree with pbl. If you're going to do gui by hand, why bother with the complicated ones meant for gui designers? pbl won't like this, but I can easily do that layout in about 5 minutes with a gui designer :)
Was This Post Helpful? 0
  • +
  • -

#5 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: JPanel not displaying properly

Posted 05 April 2013 - 06:34 AM

View Postdurby, on 05 April 2013 - 07:01 AM, said:

Changing the layout from GridBagLayout to GridLayout does not solve the problem of the JPanel not painting itself where it's supposed to be.

Never said to use a GridLayout alone, a combination of the ones I mentionned will do the job
Was This Post Helpful? 0
  • +
  • -

#6 durby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 24-October 12

Re: JPanel not displaying properly

Posted 05 April 2013 - 09:25 AM

I am now thoroughly confused.

I've isolated the problem down to the following two classes with code, layout managers aside.

The main (similar to before and not the problem class, more here if anyone wants to run it themselves):

package window;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class MainWindow extends JFrame {
	private GameBoard board = new GameBoard();
	private JPanel list = new JPanel();
	private JPanel main = new JPanel();

	public MainWindow() {
		super();
		this.setPreferredSize(new Dimension(600, 400));
		getContentPane().setLayout(new BorderLayout());

		list.setBackground(Color.GREEN);
		this.list.setPreferredSize(new Dimension(100, 100));
		getContentPane().add(list, BorderLayout.WEST);

		getContentPane().add(board, BorderLayout.CENTER);

		main.setBackground(Color.BLUE);
		this.main.setPreferredSize(new Dimension(100, 100));
		getContentPane().add(main, BorderLayout.EAST);

		pack();
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		@SuppressWarnings("unused")
		MainWindow m = new MainWindow();
	}
}



And now to the problem class:

package window;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class GameBoard extends JPanel {
	// The x and y size of the game board.
	private int x = 10;
	private int y = 15;
	private JPanel[][] map = new JPanel[x][y];

	private GridBagConstraints constraints = new GridBagConstraints();

	public GameBoard() {
		super();
		this.setBackground(Color.DARK_GRAY);
		this.setLayout(new GridBagLayout());
		setupMap();

		constraints.weightx = 1;
		constraints.weighty = 1;
		constraints.fill = GridBagConstraints.BOTH;
		drawMap();
	}

	private void setupMap() {
		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[0].length; j++) {
				map[i][j] = new JPanel();
				map[i][j].setBackground(getColor());
			}
		}
	}

	public void drawMap() {
		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[0].length; j++) {
				constraints.gridx = i;
				constraints.gridy = j;
				this.add(map[i][j], constraints);
			}
		}

		this.update(getGraphics());
	}

	private Color getColor() {
		Color c = null;
		Double r = Math.random();
		int t = (int) (5 * r);

		switch (t) {
		case 0:
			c = Color.BLACK;
			break;
		case 1:
			c = Color.BLUE;
			break;
		case 2:
			c = Color.RED;
			break;
		case 3:
			c = Color.GREEN;
			break;
		case 4:
			c = Color.YELLOW;
			break;
		default:
			c = Color.CYAN;
			break;
		}

		return c;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}
}



It seems it's the getX and getY methods (lines 80-86) is what's causing the problem.

With getX and getY:

Posted Image

Without getX and getY:

Posted Image

Any ideas why it works without getX and getY?
Was This Post Helpful? 0
  • +
  • -

#7 durby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 24-October 12

Re: JPanel not displaying properly

Posted 05 April 2013 - 09:38 AM

Apparently JComponent have getX and getY methods. So I guess when I had my own it caused weird things to happen.

Case seems to be closed. Thanks for your time.
Was This Post Helpful? 0
  • +
  • -

#8 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: JPanel not displaying properly

Posted 05 April 2013 - 10:11 AM

This is confusing and contradictory

this.setPreferredSize(new Dimension(600, 400));

pack();

what is the use of giving a Dimension to your JFrame if you ask it to pack() a few lines later ?

JFrame are BorderLayout by defautlt, no need to set it
No need to access the contentPane neither to add elements so that should do:
No need to use this. everywhere, it is confusing we try to find the other one that is not this.
especially when you use it on one line and not on the other

public class MainWindow extends JFrame {
	private GameBoard board = new GameBoard();
	private JPanel list = new JPanel();
	private JPanel main = new JPanel();

	public MainWindow() {
		super();

		list.setBackground(Color.GREEN);
		list.setPreferredSize(new Dimension(100, 100));
		add(list, BorderLayout.WEST);

		add(board, BorderLayout.CENTER);

		main.setBackground(Color.BLUE);
		main.setPreferredSize(new Dimension(100, 100));
		add(main, BorderLayout.EAST);

		pack();
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}


Now, the pack() method packs components based on the size of them... size based on the components included into these component. As far as the other class is concerned, I've never used GridBagLayout but it should sit in the center of the JFrame but with a size of 1x100 (100 because of its neighbourgs) becvuse there is no setSize() done on it or any of its components

This post has been edited by pbl: 05 April 2013 - 10:14 AM

Was This Post Helpful? 1
  • +
  • -

#9 durby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 24-October 12

Re: JPanel not displaying properly

Posted 05 April 2013 - 11:12 AM

View Postpbl, on 05 April 2013 - 10:11 AM, said:

This is confusing and contradictory
this.setPreferredSize(new Dimension(600, 400));
pack();
what is the use of giving a Dimension to your JFrame if you ask it to pack() a few lines later ?

Without the pack() I'd get a window with no size at all. The point of setting the sizes of the left and right panels is only to get their size on the x-axis and let them fill out entirelly on the y-axis. Then the center panel takes all the remaining space (of those 600 by 400).

View Postpbl, on 05 April 2013 - 10:11 AM, said:

JFrame are BorderLayout by defautlt, no need to set it
No need to access the contentPane neither to add elements so that should do:
No need to use this. everywhere, it is confusing we try to find the other one that is not this. especially when you use it on one line and not on the other

I didn't know BorderLayout was set by default or that you didn't have to get the contentPane so thanks for that.
You are probably right I do use this. to much. I'll have to get rid of that practice. Is there any "standard" way where this. should be present? Or would that only be where it's strictly necessary?

View Postpbl, on 05 April 2013 - 10:11 AM, said:

Now, the pack() method packs components based on the size of them... size based on the components included into these component. As far as the other class is concerned, I've never used GridBagLayout but it should sit in the center of the JFrame but with a size of 1x100 (100 because of its neighbourgs) becvuse there is no setSize() done on it or any of its components

The point of setting the size of the left and right panels to 100 by 100 was only to make them clearly visible while I tried to find the problem with the center panel. The middle panel needs to be bigger then 1 by 100, that's why a size of the entire window is set.

In the program where I had the problem there is no sizes set except for the 600 by 400 set on the main window, to make it the size I want it to be. The latest code I posted was only to show where the problem was and to see if anyone here knew why it was a problem. In hindsight it seems a rather silly problem and one I should have found long ago, but I didn't.
Was This Post Helpful? 0
  • +
  • -

#10 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: JPanel not displaying properly

Posted 05 April 2013 - 11:21 AM

so insteda of pack() simply do

setSize(600,400);
Was This Post Helpful? 1
  • +
  • -

#11 durby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 24-October 12

Re: JPanel not displaying properly

Posted 05 April 2013 - 11:58 AM

I see, thank you.

Is there any standard way when to use this.?
Was This Post Helpful? 0
  • +
  • -

#12 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: JPanel not displaying properly

Posted 05 April 2013 - 12:07 PM

What do you mean "standard way" ?
to use what ?

setSize(600,400) is surely a good "standard". It will be displable by most screens and then the user can enlarge/decrease the window if he wants.
Was This Post Helpful? 0
  • +
  • -

#13 Flukeshot  Icon User is offline

  • A little too OCD
  • member icon

Reputation: 401
  • View blog
  • Posts: 998
  • Joined: 14-November 12

Re: JPanel not displaying properly

Posted 05 April 2013 - 12:45 PM

this. is used to refer to an instance variable when it is being shadowed by a local variable and the same with methods, it means "this instance" and is not cryptically named. :)

This post has been edited by Flukeshot: 05 April 2013 - 12:46 PM

Was This Post Helpful? 1
  • +
  • -

#14 durby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 24-October 12

Re: JPanel not displaying properly

Posted 05 April 2013 - 02:17 PM

View Postpbl, on 05 April 2013 - 10:11 AM, said:

No need to use this. everywhere, it is confusing we try to find the other one that is not this.
especially when you use it on one line and not on the other


I meant the above quote. Since I'm obviously quite new in this programming business I'd like to not learn bad habits. So "this." should only be used when it's strictly necessary?
Was This Post Helpful? 0
  • +
  • -

#15 farrell2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 797
  • View blog
  • Posts: 2,422
  • Joined: 29-July 11

Re: JPanel not displaying properly

Posted 05 April 2013 - 02:48 PM

"this" should only be used when necessary.

private int x;

public ShapeShipConstructor(int x, int y, speed) {
    this.x = x;  //the instance variable 'x' = the local variable 'x'.
}


Was This Post Helpful? 1
  • +
  • -

Page 1 of 1