Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (536)
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  
  Components and active rendering  (Read 2193 times)
0 Members and 1 Guest are viewing this topic.
Offline M_R

Senior Newbie





« Posted 2006-05-01 04:35:05 »

I'm not sure how easy of a question this is, but I'm definitely a newless clubie, so I figured I'd try my luck here first.

I'm just getting started with active rendering, and basically from what I've read, my understanding is that it goes something like this:

while ( running ) {
    Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
    drawStuff(g);
}

Then the drawStuff() method will have the things like g.drawRect() and whatnot.  I've got the double buffering/page flipping stuff working as far as I can tell...

My question revolves around adding Swing components to my HUD/GUI.  The GUI consists of several images, placed manually by me at certain coordinates on the screen.  Each image is filled in a Rectangle..  So something like this in my drawStuff() method:

      image = (BufferedImage) images.get("right.png");
      imagePaint = new TexturePaint(image, rightRect);
      g.setPaint(imagePaint);
      g.fill(rightRect);

Now, with all of my hud elements drawn to the screen with no problem, I've left open an area in the middle where the actual game will take place.  What I want to do is display an image in that middle panel, and on top of that image have a JTextField (or something similar, if it exists) for the user to enter his/her name, along with a submit button.

I'm having a few problems with this:

1.)  I'm not sure how to go about adding a JComponent (text field, in this case) to the pane without having it get covered by the image that I'm drawing.
2.)  It seems inefficient to call this.add(text field obj) on every call that I make to drawStuff()
3.)  Creating a separate JPanel and placing it in the middle, then adding a JTextField to it, causes the JPanel to flicker a lot.

I hope I've made it clear what I want to accomplish here... It's probably a fairly elementary question, but I haven't been able to find a whole lot regarding it.  I can supply some code if necessary, but it's pretty basic atm.  Thanks
Offline Ask_Hjorth_Larsen

Junior Member




Java games rock!


« Reply #1 - Posted 2006-05-01 05:23:57 »

1) When you use active rendering the subcomponents must (AFAI can see) similarly use a kind of active rendering, since they must be drawn every time your container redraws (otherwise the container will just draw on top of them, rendering them invisible). The 'normal' way, with passive rendering, would not require any specific action, because when the panel is repainted the painting system will automatically draw sub components on top of the container. So if you can keep the subcomponents clear of the one using active rendering everything is easy, otherwise you have to actively render the text components too.
Offline M_R

Senior Newbie





« Reply #2 - Posted 2006-05-01 07:19:51 »

That's what I assumed... thanks for clarifying...

on that note, I'd like to expand my question to include "How do you actively render a JComponent?"  The best I could figure was to keep adding it to my frame, but that seemed very inefficient and there has to be an easier or better way...

I'll do some research, but if anyone has an easy answer, I wouldn't mind hearing it here  Smiley  Thanks
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline M_R

Senior Newbie





« Reply #3 - Posted 2006-05-01 07:21:00 »

I just stumbled across your thread here:  http://www.java-gaming.org/forums/index.php?&topic=12737.msg102261

I'll give it a skim

Online CommanderKeith
« Reply #4 - Posted 2006-05-01 08:00:58 »

I recently got Swing components working in my direct-rendering game, but beware because the threading issues are very difficult and Swing components are a bit of a black box.

see http://www.java-gaming.org/forums/index.php?topic=13211.0

Keith

Offline M_R

Senior Newbie





« Reply #5 - Posted 2006-05-01 08:53:27 »

I took a glance at that thread earlier and tried (but failed) to make any sense out of it  Smiley

Would it be easier to create custom input components?  All I really want are simple things like text input fields and a text output field.  a few buttons.... nothing really that fancy.  It seems that with all of the quirks of Swing components, it still might be easier to implement them than to try to make my own, given my limited knowledge.
Online CommanderKeith
« Reply #6 - Posted 2006-05-01 09:19:52 »

Just skip to Luke's post and use the code example he gives, which is a modified version of the test case I put forward. 

Simple GUI components are harder to do than you think, so I'd probably try to use Swing. 

Also, using Swing you can take advantage of the Look and Feel settings to make a colour scheme that suits your game!

Keith

Offline M_R

Senior Newbie





« Reply #7 - Posted 2006-05-01 11:18:07 »

I gave luke's example a shot and still ran into some problems (in some cases worse problems)  Smiley

I'm just going to post my code and maybe someone can tell me what I'm doing wrong... I've since reverted back to my original code, which at least seems to display stuff without the major flickering issues that I was having with Luke's example.  No doubt it was user error on my end....

A lot of this was adapted from a site online, so chances are it'll look familiar to anyone who's been to the same site, which I don't have handy at the moment, unfortunately.

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  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
236  
237  
238  
239  
240  
241  
242  
243  
244  
245  
246  
247  
248  
249  
250  
251  
252  
253  
254  
255  
256  
257  
258  
259  
260  
261  
262  
263  
264  
265  
266  
267  
268  
269  
270  
271  
272  
273  
274  
275  
276  
277  
public class BBClient extends JFrame implements Runnable, ActionListener, Observer {

private static final int NUM_BUFFERS = 2;
private static final int NO_DELAYS_PER_YIELD = 16;
private static int MAX_FRAME_SKIPS = 5;
private int period;
private GraphicsDevice gd;
private Graphics2D gScr;
private BufferStrategy bufferStrategy;
private HashMap images;
private Thread animator;
private boolean running;

// Button Rectangles/Areas
private Rectangle leftRect;
private Rectangle topRect;
private Rectangle rightRect;
private Rectangle bottomRect;
private Rectangle nukeRect;
private Rectangle cannonRect;
private Rectangle connectRect;
private Rectangle chatButtonRect;
private Rectangle chatBarRect;
private Rectangle switchRect;
private Rectangle contentRect;

// Hover vars -- Right now I only have the "connect" button implemented...
private boolean isOverConnectRect;

// Stage vars

private int stage;
private JPanel gridPane;

// at different “stages,” the user can interact with different things.  Not important right now

private JLabel bgImage;
private JTextField loginField;
private static final long serialVersionUID = 1L;

public BBClient(int period) {
   super("MyGame");
   this.period = period;
   setIgnoreRepaint(true);

   stage = 0;  // no importance right now
  loadImages();
   createRects();
   initFullScreen();

   // I colored the background green to see what space the JPanel actually occupies.  
  // From the looks of it, the JPanel is in the right space in the GUI, and it's the right size.  
  // However the components within it are all screwed up and out of place.

   gridPane = new JPanel();
   gridPane.setBackground(Color.green);

   // Load the "login" image that will serve as a sort of splash/intro screen while the player logs in
  try {
      String url = System.getProperty("user.dir")+ "\\view\\images\\login.png";
      bgImage = new JLabel(new ImageIcon(new URL("file:" + url)));
   } catch (Exception e) {
      System.out.println("wra!");
   }

   // I've tried all sorts of ways to reposition the bgImage JLabel, to no avail.  
  // It always appears offset to the right in the JPanel no matter what I do.
  // I've also tried to add a JTextField here, also to no avail.  textfield.setSize(x, y) also seems to have no effect.

   gridPane.add(bgImage);
   gridPane.add(new JTextField());

   add(gridPane);

   gameStart();
}

// ImageLoader is a separate class
public void loadImages() {

   // … this part’s not a problem, but it sure is too lengthy to post here  :)

}

// We'll be able to interact with some of these later on, but for now we're just using them for image placement.
public void createRects() {

   leftRect = new Rectangle(0, 0, 173, 600);
   // … etc

}

public void initFullScreen() {
   GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
   gd = ge.getDefaultScreenDevice();

   setUndecorated(true);
   setIgnoreRepaint(true);
   setResizable(false);

   if (!gd.isFullScreenSupported()) {
      System.out.println("Couldn't get into full-screen...");
      System.exit(0);
   }
   gd.setFullScreenWindow(this); // switch on full-screen mode

   setDisplayMode(800, 600, 32); // set the resolution so the GUI fits

   setBufferStrategy(); // set up the drawing/rendering mechanisms
}

private void setDisplayMode(int width, int height, int bitDepth) {
   if (!gd.isDisplayChangeSupported()) {
      System.out.println("Display mode changing not supported");
      return;
   }
   DisplayMode dm = new DisplayMode(width, height, bitDepth,
   DisplayMode.REFRESH_RATE_UNKNOWN);
   try {
      gd.setDisplayMode(dm);
   } catch (IllegalArgumentException e) {
      System.out.println("Error setting Display mode (" + width + ","   + height + "," + bitDepth + ")");
   }
   try {
      Thread.sleep(1000);
   } catch (InterruptedException ex) {
   }
}

private void setBufferStrategy() {
   try {
      EventQueue.invokeAndWait(new Runnable() {
      public void run() {
         createBufferStrategy(NUM_BUFFERS);
      }
      });
   } catch (Exception e) {
      System.out.println("Couldn't start page flipping...");
      System.exit(0);
   }

   // Allow the new BufferStrategy enough time to execute
  try {
      Thread.sleep(500); // 0.5 sec
  } catch (InterruptedException ex) {
   }

   bufferStrategy = getBufferStrategy(); // store for later
}

// Start our main game thread
private void gameStart() {
   if (animator == null || !running) {
      animator = new Thread(this);
      animator.start();
   }
}

public void run() {

   // Framerate and timer settings have no relevance to my current problem

   running = true;

   while (running) {
      screenUpdate();
      // framerate stuff goes below here…
  }
   closeGame();
}

public void screenUpdate() {
   try {
      gScr = (Graphics2D) bufferStrategy.getDrawGraphics();
      gameRender();
      gScr.dispose();

      if (!bufferStrategy.contentsLost()) {
         bufferStrategy.show();
      } else {
         System.out.println("Contents Lost");
      }

      Toolkit.getDefaultToolkit().sync();
   } catch (Exception e) {
      e.printStackTrace();
      running = false;
   }
}

// Here's where the actual drawing takes place.  This is called from screenUpdate which is called from
// our main run loop. The first part of this section simply draws my HUD.  It basically creates a "BorderLayout"
// of my own, with images on the left, top, right and bottom.  The middle of the screen is left empty and shouldn't
// be drawn in.... yet.

public void gameRender() {
   BufferedImage image;
   TexturePaint imagePaint;

   image = (BufferedImage) images.get("left.png");
   imagePaint = new TexturePaint(image, leftRect);
   gScr.setPaint(imagePaint);
   gScr.fill(leftRect);

   image = (BufferedImage) images.get("top.png");
   imagePaint = new TexturePaint(image, topRect);
   gScr.setPaint(imagePaint);
   gScr.fill(topRect);

   image = (BufferedImage) images.get("right.png");
   imagePaint = new TexturePaint(image, rightRect);
   gScr.setPaint(imagePaint);
   gScr.fill(rightRect);

   image = (BufferedImage) images.get("bottom.png");
   imagePaint = new TexturePaint(image, bottomRect);
   gScr.setPaint(imagePaint);
   gScr.fill(bottomRect);

   // If this is the Login stage (which, right now, is the only stage that exists), draw the splash logo
  // and login components (JTextField and JButton, for example)
 
   if (stage == 0) {
      Graphics2D g2d = (Graphics2D)gScr.create(173, 93, 550, 421);
      gridPane.paint(g2d);
   
      // gridPane.paintComponents(g2d) results in 2 of my "splash images" being drawn on the screen.  
     // One is solid and displayed off-center, while the other is flickering with a green background
     // (I set the gridPane JPanel's background to green, if you recall).

      // gridPane.repaint() causes the entire screen to flicker.  The HUD images and the JPanel flicker between one another.
     
      // Right now gridPane.paint(g2d) yields the best results, showing the solid splash image from my JLabel (no flickering),
     // but showing it off-centered.  Again, my JTextField wouldn't show up either when I tried to add it.  
     // Trying to reposition the JComponents yields no results.  The only way I seem to be able to move anything is if
     // I move the rectangle that it's all drawn in.  This is unacceptable, as it would cause it to cover up the other
     // elements on the screen, such as the HUD.
  }

   // Not important for the purposes of my current problem.  It works when I actually have it implemented.
  if (isOverConnectRect) {
      this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
      image = (BufferedImage) images.get("h_connect.png");
      imagePaint = new TexturePaint(image, connectRect);
      gScr.setPaint(imagePaint);
      gScr.fill(connectRect);
   } else {
      this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
   }
}


public void closeGame() {
   Window w = gd.getFullScreenWindow();
   if (w != null) {
      w.dispose();
   }
   gd.setFullScreenWindow(null);
   System.exit(0);
}


public void update(Observable o, Object arg) {
}

public void actionPerformed(ActionEvent e) {
}

public static void main(String[] args) {
   int p = 1;
   new BBClient(p).setVisible(true);

   // I've noticed that removing the call to setVisible here causes my JPanel to not get drawn at all...
  // I thought JFrames were visible by default?
}

}



I appreciate the help of anyone who's willing to take the time to sift through my crappy coding and help me figure out what I'm doing wrong.  This seems to be a question that's asked all-too-often, yet it's strange how it's still so difficult to find a straight answer.  Thanks again.
Offline M_R

Senior Newbie





« Reply #8 - Posted 2006-05-01 13:58:21 »

I actually made some semblance of progress by trial and error........ if this is how it's SUPPOSED to be done, then shame on Sun  Smiley

Right now I have my background/splash image drawing at the correct location -- I had to use a rather peculiar way of positioning it, though, and it goes through a strange "fade in" when it's first drawn.

On top of that splash image, I also have my JTextField displayed.  Unfortunately, I'm unable to set the location/position of this JTextField, however I AM able to set its size.  Why this is the case, God only knows.  I'm also unable to edit the JTextField,even if I have setEditable(true)....

Here's my revised code... now instead of adding the components to a JPanel (which I would dearly like to do), I just instantiate them, and then individually call their paint() methods from my game loop... this seems idiotic, but it's teh closest I've gotten it to working....

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  
   private JLabel bgImage;
   private JTextField loginField;

   public BBClient(int period) {
      super("MyGame");
      this.period = period;
      setIgnoreRepaint(true);

      loadImages();
      createRects();
      initFullScreen();

                // Editing the x,y values in setBounds yields no results.  e.g. - I'm unable to reposition this JPanel.  The only way I can change it is by changing its size.
               // This is pretty odd....
     try {
         String url = System.getProperty("user.dir")
               + "\\view\\images\\login.png";
         bgImage = new JLabel(new ImageIcon(new URL("file:" + url)));
         bgImage.setBounds(0, 0, 550, 421);
         bgImage.setIgnoreRepaint(true);
      } catch (Exception e) {
         System.out.println("wra!");
      }

      loginField = new JTextField("OMGZZZ!!");
      loginField.setSize(1000, 30);  // This works....
               loginField.setLocation(250, 25); // This doesn't.... it's always displayed at (0,0) in relation to the Graphics2D area that it's drawn in.  So actually (173,93)
     loginField.setEditable(true);  // This doesn't work either...
     loginField.setEnabled(true); // setEnabled() works, however it only controls whether the field is lit up, or dimmed out.  It doesn't affect whether or not I can edit it
     loginField.setIgnoreRepaint(true);

      gameStart();  // Calls my main run() loop, which then calls the gameRender() method

       }

       public void gameRender() {
                // gScr is my main graphics object.... here I'm creating a new Graphics2D object to draw in a certain area
               // so as to avoid drawing over my loaded HUD image elements.

                // Position the rectangle or drawing area/canvas of this graphics object in the middle pane area where the content should go.
     Graphics2D g2d = (Graphics2D) gScr.create(173, 93, 550, 421);
      bgImage.paint(g2d);  // I have to call each component's paint() method individually
     loginField.paint(g2d); // Calling paintcomponent() or anything else yields unhappy results...
       }



Maybe it's a little more clear what's going on in my funky code now............ I appreciate any help.

Offline Ask_Hjorth_Larsen

Junior Member




Java games rock!


« Reply #9 - Posted 2006-05-01 15:19:46 »

I think your problem is that you call the paint method of the text field directly. I believe your graphics object should have the correct clip and translation first.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline M_R

Senior Newbie





« Reply #10 - Posted 2006-05-01 16:24:00 »

Could you elaborate on that?

I have the Graphics2D object, gScr which is used to paint the rest of the UI -- HUD elements, etc.

I do gScr.create() to create another graphics object (or duplicate) in the area that I want my content pane to be drawn.

Then I pass it to component.paint(g2d) to draw that specific component.

What other way is there to do this?

I tried doing Graphics2D g2d = loginField.getGraphics()
then loginField.paint(g2d)

but got an exception.... i'm guessing that's not what you meant, but I'm a little unclear

[edit]

Actually I think I get what you meant.  So I basically have to g.create() for every component that I want to add in a different location.  Doing that, I was able to reposition my JTextField, however I still have the problem of not being able to edit the text in it.  Is this tied in to the paint method somehow or is there something else that's causing this issue?
Offline Ask_Hjorth_Larsen

Junior Member




Java games rock!


« Reply #11 - Posted 2006-05-01 23:56:41 »

The paint method assumes that the Graphics object has to correct translational transform and the correct clipping region.

However you have not specified these two. When you write a paint method you NEVER think about the location of the component, because the painting system will already have applied to correct clip/transform (and perhaps other things I have not thought of). This is why your component is indifferent to its location graphically: it draws itself at (0,0), so you have to change the Graphics object to make sure (0,0) in this context corresponds to the correct point of your container.
Offline M_R

Senior Newbie





« Reply #12 - Posted 2006-05-02 00:10:46 »

Thanks for the explanation.  I've now got it drawing in the correct place, and updating properly, however the setEditable() method still won't let me edit it.... any idea why that may be?  I'll continue my usual method of trial & error and hope I can find a fix.... thanks for your help
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.

Riven (19 views)
2014-07-29 18:09:19

Riven (13 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

E.R. Fleming (31 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (42 views)
2014-07-24 01:59:36

Riven (42 views)
2014-07-23 21:16:32

Riven (28 views)
2014-07-23 21:07:15

Riven (29 views)
2014-07-23 20:56:16

ctomni231 (60 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
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!