Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (497)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Specify What To Paint On? (Java2D)  (Read 2071 times)
0 Members and 1 Guest are viewing this topic.
Offline tyeeeee1
« Posted 2013-01-02 08:20:23 »

I've been trying to figure out a way to draw a map onto a JPanel for the past week or so and my current solution should work, my only problem is that I can't figure out how to tell my paint method to paint onto my JPanel which is named gamePanel. I've tried looking up how to specify which JPanel to paint onto but it hasn't yielded much information.

Small Snippit:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
class Maps extends JPanel
{
   int testMap[][] = new int[2][2];
   boolean[][] testCollisionMap= new boolean[2][2];
   int tempIntOne = 0, tempIntTwo = 0;
   JPanel gamePanel;
   
   public Maps(JPanel gamePanel)
   {
      this.gamePanel = gamePanel;
      testMap[0][0] = 1;
      testMap[0][1] = 2;
      testMap[1][0] = 1;
      testMap[1][1] = 2;
      testCollisionMap[0][0] = false;
      testCollisionMap[0][1] = true;
      testCollisionMap[1][0] = false;
      testCollisionMap[1][1] = true;
   }
   
   public void paint(Graphics2D g)
   {
      for(int i = -1; i <3; i++) //For the part (i < 1) just replace the 1 with the max number it goes to.
     {
         if (testMap[tempIntOne][tempIntTwo] == 1)
         {
            g.setColor(Color.blue);
            g.fillRect(50, 50, 20, 20);
            g.drawRect(50, 50, 20, 20);
         }
         else
         {
            g.setColor(Color.red);
            g.fillRect(100, 100, 20, 20);
            g.drawRect(100, 100, 20, 20);
         }
         
         if (tempIntTwo == 1)
         {
            tempIntOne++;
         }
         else
         {
            tempIntTwo++;
         }
      }
   }
   
}


I don't remember too much about painting and that from the applets section in my class but I'd assume this should work if I can somehow say what to paint onto.

~Thanks in advance.
Offline 65K
« Reply #1 - Posted 2013-01-02 09:01:21 »

Your class extends from a JPanel, so it is a JPanel, but at the construction time you feed it with another panel or with itself ?

Offline tyeeeee1
« Reply #2 - Posted 2013-01-02 09:09:13 »

Your class extends from a JPanel, so it is a JPanel, but at the construction time you feed it with another panel or with itself ?


I'm feeding the constructor the JPanel, known as gamePanel, from another class so that I can paint on the gamePanel from the Maps class.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline 65K
« Reply #3 - Posted 2013-01-02 09:13:42 »

Then use JPanel#getGraphics to get the context of the other panel to draw on and do not override paint.

Offline tyeeeee1
« Reply #4 - Posted 2013-01-02 09:21:09 »

I just took a quick look at the API for getGraphics() and I managed to implement it without any compile errors, after testing my program nothing was drawn on the JPanel; Have I incorrectly implemented getGraphics()?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
class Maps extends JPanel
{
   int testMap[][] = new int[2][2];
   boolean[][] testCollisionMap= new boolean[2][2];
   int tempIntOne = 0, tempIntTwo = 0;
   JPanel gamePanel;
   
   public Maps(JPanel gamePanel)
   {
      this.gamePanel = gamePanel;
      testMap[0][0] = 1;
      testMap[0][1] = 2;
      testMap[1][0] = 1;
      testMap[1][1] = 2;
      testCollisionMap[0][0] = false;
      testCollisionMap[0][1] = true;
      testCollisionMap[1][0] = false;
      testCollisionMap[1][1] = true;
   }
   
   public void drawMap()
   {
      Graphics g = gamePanel.getGraphics();
     
      for(int i = -1; i <1; i++) //For the part (i < 1) just replace the 1 with the max number it goes to.
     {
         if (testMap[tempIntOne][tempIntTwo] == 1)
         {
            g.setColor(Color.blue);
            g.fillRect(50, 50, 20, 20);
            g.drawRect(50, 50, 20, 20);
         }
         else
         {
            g.setColor(Color.red);
            g.fillRect(100, 100, 20, 20);
            g.drawRect(100, 100, 20, 20);
         }
         
         if (tempIntTwo == 1)
         {
            tempIntOne++;
         }
         else
         {
            tempIntTwo++;
         }
      }
   }
   
}



Edit: I just did a quick check with a few System.out.println lines, the code is being executed properly it's just not drawing anything on the JPanel.

Edit2: Did another test to make sure that 'g' was being set to gamePanel.getGraphics() and it seemed to be. The message that was printed was:
"sun.java2d.SunGraphics2D[font=javax.swing.plaf.FontUIResource[familt=Dialog,name=Dialog,style=plain,size=12],color=java.awt.Color[r=0,g=0,b=0]]"
Offline 65K
« Reply #5 - Posted 2013-01-02 09:28:12 »

Can't tell without the whole context and setup. Maybe the overall component handling / class structure is faulty.
But anyway, I do not see why one JPanel should draw the game map on another JPanel.
The Maps class should be independent of a concrete component, it should just draw on one.

Offline tyeeeee1
« Reply #6 - Posted 2013-01-02 09:32:37 »

Can't tell without the whole context and setup. Maybe the overall component handling / class structure is faulty.
But anyway, I do not see why one JPanel should draw the game map on another JPanel.
The Maps class should be independent of a concrete component, it should just draw on one.

O.o That's not what I was trying to do... I'm trying to create a class that, after it's constructed and the 'drawMap()' method is called, the map will be drawn on the programs JPanel which I've named gamePanel. It's not supposed to do anything with a second JPanel, all the drawMap() method should do is draw onto the gamePanel when called.
The Maps class is just some random placeholder/test class that I'm working with to figure out how to get it all working before I re-write it all and make a proper map loading class.

*If I'm not making any sense, it's almost 6am here so I'm half-awake.

Edit:
You probably wont be able to figure my code out since it's all one file but here is the full program so-far... http://pastebin.ca/2298639 The Maps class is being constructed around line 1100
Offline Phibedy

Senior Member


Medals: 8



« Reply #7 - Posted 2013-01-02 09:53:32 »

I also have an [map].draw function but I did it like this:
Why does your gamepanel extend Jpanel?
pseudo-code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
GamePanel.class:
private Map map;
[...]
public void paint (Graphics g) {
      Render.map(map,g);
}

Map.class
private JComponent comp; //I wouldn't use it that way, I prefere independent mapobjects

public Map(JComponent comp) {
[...]
      this.comp = comp;
   }

render(){
[Here you could check if Jcomp has focus etc]
[set the map in the GamePanel.class (if you need to)]
comp.repaint();
}
I don't like that pseudo that much, but it works.

It should also be possible to use:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
GamePanel.class
public Graphics paint (Graphics g) {
      return g;
   }


Map.class
private JComponent comp;
public Map(JComponent comp) {
[...]
      this.comp = comp;
   }

render(){
Graphics g = comp.repaint();
[draw with g]
}



Edit:
Are you sure, that you don't want to use more .class files?

best regards
Offline tyeeeee1
« Reply #8 - Posted 2013-01-02 10:07:03 »

Thanks for the examples, they gave me an idea that might be able to solve this problem or something. Hopefully I don't forget when I wake up; I would use more.class files but I haven't bothered to learn how to use more than one class file yet. Apparently my CS class was only for the very very basics, it didn't tell me much...
Offline Phibedy

Senior Member


Medals: 8



« Reply #9 - Posted 2013-01-02 10:25:00 »

Sry for code-block  Smiley
How I did it, I hope I haven't earsed to much of my code, if you have questions left, feel free to ask.
Main:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public class Main {
   
   public static String version = "V 0.1 - Alpha";
   public static int width = 1280;
   public static int height = 720;
   public static GameWindow gameWindow;
        public static boolean paused;
   
   public static void main(String[] args) throws IOException{
      gameWindow = new GameWindow("Game " + version, width, height);
   }
}

JFrame:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
public class GameWindow extends JFrame {
   private static final long serialVersionUID = 1308619767172296296L;
   private Dimension dim;
   private GamePanel gpanel;
   public static GameWindow gw;
   
   public GameWindow(String title, int width, int height) throws IOException {
     
      super(title);
      gw = this;
      dim = new Dimension(width, height);
           
      setMaximumSize(dim);
      setMinimumSize(dim);
      setPreferredSize(dim);
     
      gpanel = new GamePanel();
      add(gpanel);
     
      setLocationRelativeTo(null);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setResizable(false);
     
      setUndecorated(true);
      setVisible(true);
     
   }


JPanel attached on the Jframe
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public class GamePanel extends JPanel{
public GamePanel() throws IOException {
      super();  
      this.setLayout(null);
      KeyOptionsPanel.loadKeys();

      moveThread = new MoveThread(this); //Gameloop
     start = new Thread(moveThread);
      start.start();
   }
   
   
   public void paint (Graphics g) {
      Render.map(g); //in my ressourcemanager.class is the current map, that will be rendered
  }
}


Gameloop:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
        public class MoveThread implements Runnable{
   private JComponent comp;
   private long duration, last = System.currentTimeMillis() - 20;
   
   public MoveThread(JComponent comp) {
      this.comp = comp;
   }
   
   @Override
   public void run() {
      while (Main.running) {
     
         duration = System.currentTimeMillis() - last;
         last = System.currentTimeMillis();
                 
         if (!Main.paused) CalculateMov.cm.run(duration); //Calculates playermov etc.
       
         comp.repaint();
         
         try {
            Thread.sleep(20);
         } catch (InterruptedException e) {
         }
      }
   }
}

I wouldn't use that gameloop anymore, that was my first one Cheesy
I would recomment that one: http://www.java-gaming.org/topics/game-loops/24220/view
If you use java2d, use the "double-buffered-renderer"
You don't have to render Tiles, that aren't shown. It's a little bit tricky but to save performance, you can create an "startTileX", "startTileY" and "stopTileX", "stopTileY".
You get the startTile[x/y] if you devide the cameraMovement by the size of one tile -> stopTile[x/y] = startTile[x/y] +[width/height] devided by size of one tile.
The "/" isn't an mathematical sign, I am just to lazy to write it for x and y Smiley
best regards
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tyeeeee1
« Reply #10 - Posted 2013-01-02 20:20:29 »

I figured this out last night but I forgot it after I went to sleep.  Undecided I just did a few tests as well as trying to mess around with the code a bit to get it working; As far as I've been able to figure out, everything is working as intended (except my little if statement to increase the numbers to go through the array) but it's just not painting onto the JPanel.

Although I'm doing "Graphics g = gamePanel.getGraphics();" and then doing things like "g.fillRect(50, 50, 20, 20);" none of it is being draw onto the JPanel, gamePanel. I had an idea that it might be because I'm not using "gamePanel.repaint();" but that didn't do anything.
Offline 65K
« Reply #11 - Posted 2013-01-03 08:22:17 »

You probably wont be able to figure my code out since it's all one file but here is the full program so-far... http://pastebin.ca/2298639 The Maps class is being constructed around line 1100
If that is your current project, it cannot work because you calling the draw method only once before the game loop gets started - painting has to happen inside the game loop.
Another point: there are a lot of JFrame inherited classes for menus.
Only inherit if you need to, meaning to modify or add functionality which is not the case here.
For menus you should rather create one frame and replace its content pane according to the current screen.

You should also decide whether to use active or passive (bad for games) rendering with Swing/Java2D.

Offline tyeeeee1
« Reply #12 - Posted 2013-01-03 17:31:25 »

If that is your current project, it cannot work because you calling the draw method only once before the game loop gets started - painting has to happen inside the game loop.
Another point: there are a lot of JFrame inherited classes for menus.
Only inherit if you need to, meaning to modify or add functionality which is not the case here.
For menus you should rather create one frame and replace its content pane according to the current screen.

You should also decide whether to use active or passive (bad for games) rendering with Swing/Java2D.

Thanks for the tips/information. I learned to use Swing by looking up random things on google (usually not on the oracle tutorials) so I had always thought that I just had to use 'extends JFrame' if JFrame was being used, I removed them now and everything still works which is awesome  Cheesy. My problem about painting on the screen has been solved now as well, I just inserted my code into the game loop with a boolean check and it rendered to the screen.

Could you elaborate on the menus replacing panes and that, I don't compeltely get what you mean. As for the rendering; I've seen a lot of pages on google that show, IMO, overly complicated game loops with double buffering and that. After a bit more googling I saw somewhere that the JPanel automatically does double buffering so it should be fine to use for simple games.

Thanks a ton for the help!  Grin
Offline 65K
« Reply #13 - Posted 2013-01-04 08:07:32 »

Could you elaborate on the menus replacing panes and that, I don't compeltely get what you mean.
Just create one main JFrame and as many JPanels, Canvases or whatever and place them into the content pane of the JFrame as needed.
JFrame#getContentPane().add(...)
JFrame#getContentPane().remove(...)
(as far as I remember)

As for the rendering; I've seen a lot of pages on google that show, IMO, overly complicated game loops with double buffering and that. After a bit more googling I saw somewhere that the JPanel automatically does double buffering so it should be fine to use for simple games.
If that works for you without visual artefacts, then it is fine.

Offline tyeeeee1
« Reply #14 - Posted 2013-01-05 02:57:28 »

Ah, that makes a lot more sense now. One final question before I go off and do a big re-write; is there any advantage to creating multiple JPanels and then switching them up from menu to menu ?
Offline 65K
« Reply #15 - Posted 2013-01-05 12:10:32 »

is there any advantage to creating multiple JPanels and then switching them up from menu to menu ?
Not sure if I understand, if you have lots of individual components you better create separate panels.

Offline supaFool

Junior Member


Projects: 2



« Reply #16 - Posted 2013-01-07 17:22:52 »

Ah, that makes a lot more sense now. One final question before I go off and do a big re-write; is there any advantage to creating multiple JPanels and then switching them up from menu to menu ?

Yes. It will Improve loading speeds.
Offline Phibedy

Senior Member


Medals: 8



« Reply #17 - Posted 2013-01-07 21:32:28 »

In got several Panels:
MainPanel (@gamestart),
GamePanel,
option-panel,
loading-panel,
singleplayerpanel,
multiplayerpanel,
debugger-panel,
etc. I don't like to switch components off and on, I pefere creating new panels, if it's worth it Smiley
best regards
Offline BoBear2681

JGO Coder


Medals: 18



« Reply #18 - Posted 2013-01-07 22:39:02 »

Not sure if this is what you're asking for, but if you want to display different panels as the "main" content pane, depending on certain criteria, then CardLayout is what you're after.

As for whether it's worth it to create them up front vs. creating new ones on the fly, the answer is: do whatever you want, as long as it performs well enough.  If you can create your panels fast enough that lazily creating them shows no perceivable performance issue to the user, then why not?
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #19 - Posted 2013-01-07 23:42:00 »

I disagree with the listed approaches. You should pretty much never use getGraphics() because the timing of the drawing will not be correct most of the time. The drawing will happen on the EDT, and part of the paintComponent function is to clear the previous frame. As a result, you'll get synchronization issues and a lot of flickering.

You should have each panel use its own paint or paintComponent method and then pass its Graphics object to whatever should be drawing in it. Just the way you've organized everything defeats the purpose of the Object hierarchy you're already given. Each panel should be able to draw what it wants, someone else should not be telling a panel when to draw.

See my work:
OTC Software
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

UprightPath (2 views)
2014-09-20 20:14:06

BurntPizza (26 views)
2014-09-19 03:14:18

Dwinin (40 views)
2014-09-12 09:08:26

Norakomi (70 views)
2014-09-10 13:57:51

TehJavaDev (95 views)
2014-09-10 06:39:09

Tekkerue (49 views)
2014-09-09 02:24:56

mitcheeb (70 views)
2014-09-08 06:06:29

BurntPizza (52 views)
2014-09-07 01:13:42

Longarmx (39 views)
2014-09-07 01:12:14

Longarmx (45 views)
2014-09-07 01:11:22
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!