I'm trying to program a small game applet (of course ;-)
and am using GridBagLayout (JDK 1.1) to place my components.
My problem is that the component in the top left corner
which will represent the playing field is too small.
Increasing the weightx and weighty doesn't help.
I've tried to create a small test case and have exchanged
the playing field component against a button (named "play"
in the code below). Could someone please help me?
I also wonder why do the buttons 1, 3, 5 and 7 appear
wider than their 0, 2, 4 and 6 brothers?
I've put the applet and the code (also pasted below)
at this address: http://pref.dyndns.org/grid/grid2.html
Regards
Alex
public class Grid2 extends Applet implements Runnable
{
Button but[];
TextArea area;
TextField field;
Label label;
// How to make the button below bigger?
Button play;
public void init() {
// create the components
but = new Button[8];
for (int i = 0; i < but.length; i++)
but[i] = new Button("Button " + i);
area = new TextArea();
area.setEditable(false);
label = new Label("Enter text here: ", Label.RIGHT);
field = new TextField();
play = new Button("Too small...");
// set the layout manager
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints constr = new GridBagConstraints();
constr.fill = GridBagConstraints.BOTH;
constr.ipadx = 2;
constr.ipady = 2;
setLayout(gridbag);
// give max. space to the playing board
// height = 4 buttons + 1 TextArea
constr.gridx = 0;
constr.gridy = 0;
constr.weightx = 20;
constr.weighty = 20;
constr.gridwidth = 1;
constr.gridheight = 5;
gridbag.setConstraints(play, constr);
add(play);
// put label as status bar below the board
constr.gridx = 0;
constr.gridy = 5;
constr.weightx = 0;
constr.weighty = 0;
constr.gridwidth = 1;
constr.gridheight = 1;
gridbag.setConstraints(label, constr);
add(label);
// create 4 rows with 2 buttons on each
constr.weightx = 0;
constr.weighty = 0;
constr.gridwidth = 1;
constr.gridheight = 1;
for (int i = 0; i < but.length; i++) {
constr.gridx = 1 + i % 2;
constr.gridy = (int)(i / 2);
gridbag.setConstraints(but[i], constr);
add(but[i]);
}
// Create text area
constr.gridx = 1;
constr.gridy = 4;
constr.weightx = 0;
constr.weighty = 0;
constr.gridwidth = 2;
constr.gridheight = 1;
gridbag.setConstraints(area, constr);
add(area);
// Create text field for input
constr.gridx = 1;
constr.gridy = 5;
constr.weightx = 0;
constr.weighty = 0;
constr.gridwidth = 4;
constr.gridheight = 1;
gridbag.setConstraints(field, constr);
add(field);
}
public synchronized void run() {
}
}
Yes, of course you are.
I will point out however, that if I
understand your intent correctly,
this design would be relatively easy
to implement using nested
BorderLayouts and GridLayouts.
--
Andrew Thompson
* http://www.PhySci.org/ Open-source software suite
* http://www.PhySci.org/codes/ Web & IT Help
* http://www.1point1C.org/ Science & Technology
A:
GridbagConstraints is probably one of the most complicated things in
Java. I use it all the time and find it very frustrating. One thing
that you need to consider is that all of the components will affect the
others when it is layed out. One thing that will help especially if you
have a component that you want a certain size is to make sure it tells
the Layout manater what size it wants to be. Do that with
getPreferredSize(), getMaximunSize() and getMinimumSize(). Override
these methods in your game component and that will help. One the other
hand your little test Applet just needs two small changes to make the
"Too Small..." button bigger. See what I changed in your code above.
Also, one thing to save you some coding, when you add your components
you can use the add() that takes a constraint, add(comp,constr).
--
Knute Johnson
email s/nospam/knute/
Molon labe...
In article <2a8bdbdb8bff4b5b...@news.1usenet.com>, Knute
Johnson <nos...@sagebrush.frazmtn.com> wrote:
> GridbagConstraints is probably one of the most complicated things in
> Java. I use it all the time and find it very frustrating.
Take a look at Foam which will likely increase your productivity over
using GridBagLayout. It's a very easy to use visual designer. I
recommend viewing one or two of the demo movies to get an idea of how
Foam can help!
http://www.computersinmotion.com
--
Cheers,
Graham Perks.
Computers In Motion
> GridbagConstraints is probably one of the most complicated things in
> Java. I use it all the time and find it very frustrating. One thing
> that you need to consider is that all of the components will affect the
> others when it is layed out. [...]
I've found in my layout courses that developers can work
much better with layouts if a mental layout can be built
from a fixed set of code that does not grow with the number
of components as is the case with GridBagLayout.
I've observed this difference between GridBagLayout and
Daniel Barbalace's TableLayout. TableLayout defines a grid,
then adds components to this grid. I tried to simplify
the TableLayout's grid definition mechanism and the result
is the FormLayout grid specification where you can
describe most layout with two lines of code.
The primary goal is to make simple things easy.
Secondary goals are to make the hard stuff possible,
the good design easy and the bad difficult.
But whenever I added a feature to the FormLayout
the driving rule was to make it an option, so that
it won't stiffle your productivity for simple layouts.
For example, I've incoporated the HIGLayout features
for giving a set of columns the same width, and have
added a bunch of pixel-independent sizes.
I can wholeheartly recommend to give FormLayout a try.
Many developers have reported that they could save
time and money using FormLayout and the helper classes
that build the Forms layout system. And some
developers even report that they started to enjoy
implementing layouts.
Since the Forms layout system is free of charge,
I'd say it is worth a try. Find it here:
http://forms.dev.java.net/
A demo that shows many essential layout tasks
that you *cannot* implement with GridBagLayout
and TableLayout can be found here:
http://www.jgoodies.com/freeware/formsdemo/
Recently Jeanette Winzenburg has published a preview
of an advanced visual editor for the FormLayout and
its optional classes. See
http://www.swingempire.de/palace/FormBuilder
Hope this helps you overcome your layout frustration.
Best regards,
Karsten Lentzsch
Knute Johnson <nos...@sagebrush.frazmtn.com> wrote in message news:<2a8bdbdb8bff4b5b...@news.1usenet.com>...
> A. Farber wrote:
> > My problem is that the component in the top left corner
> > which will represent the playing field is too small.
> GridbagConstraints is probably one of the most complicated things in
> Java. I use it all the time and find it very frustrating. One thing
> that you need to consider is that all of the components will affect the
> others when it is layed out. One thing that will help especially if you
> have a component that you want a certain size is to make sure it tells
> the Layout manater what size it wants to be. Do that with
> getPreferredSize(), getMaximunSize() and getMinimumSize(). Override
> these methods in your game component and that will help. One the other
> hand your little test Applet just needs two small changes to make the
> "Too Small..." button bigger. See what I changed in your code above.
thank you for your reply! As I changed the component's
gridwidth to 3, the applet looked exactly as I wanted.
The TextField has been however covered by the label,
so that I had to update it's gridx and labels gridwidth.
The strange thing is however that if I update the
TextArea's gridx to 3 as well (since it is exactly below
the Buttons 0,2,4,6) then everything looks strange again.
You can see it at http://pref.dyndns.org/grid/grid2.html
Anyway, I of course don't want to have a Button there
but my own component, which will display playing cards.
My problem is, I'm not sure how to implement the
getPreferredSize() and getMinimumSize() if I'd like
my component to occupy 80% of the applet. Where
would I get the applet's dimensions, should I pass
them through the constructor?
Also do I have to implement setBounds() and setSize()
as well? Especially since I'm going to use an offscreen
Graphics for painting that component (and it's
dimensions will change if my component is resized).
Please see the bottom of http://pref.dyndns.org/grid/Grid2.java
to see what I mean. Thank you for your help
Regards
Alex
That is fairly simple if you aren't trying to be too tricky. And yes
you would pass them through init() or the constructor if you were going
to set the size of your component to some percentage of the size of the
Applet. The nice thing about an Applet is that you pretty much know
what size it is going to be because it is specified in the HTML document.
> Also do I have to implement setBounds() and setSize()
> as well? Especially since I'm going to use an offscreen
> Graphics for painting that component (and it's
> dimensions will change if my component is resized).
> Please see the bottom of http://pref.dyndns.org/grid/Grid2.java
> to see what I mean. Thank you for your help
Probably not but it depends on what you are tyring to do.
Since GridbagLayout can be difficult, sometimes it is better to use some
of the simpler layouts and mix them. Your project here would work
really well if you used a BorderLayout and put the big button (or
whatever) in the center, the Label and TextArea on a Panel with
FlowLayout and then the Panel on the south of the BorderLayout. And
finally the buttons in a GridLayout on their own Panel and then on the
east of the BorderLayout. Of course GridbagLayout can do it all which
is nice too.
I looked at your code for your Board. I would extend Panel as you can
draw directly to it's Graphics. Unless you are going to animate it you
probably won't need to double buffer it. If you do you can get an Image
from Component.createImage(). Draw on that and then in your paint()
draw the image to the component. If you are going to double buffer it,
override update() and have it call paint(). update() normally clears
the drawing area with the background color and then calls paint().
I've laid out the components as I wanted now.
However if I replace the Button "play" with
my own component "Board", which implements:
public Board() {
font = new Font("SansSerif", Font.PLAIN, 12);
minSize = new Dimension(640, 480);
}
public Dimension getMinimumSize() {
return minSize;
}
public Dimension getPreferredSize() {
return getMinimumSize();
}
and then detach the applet to a frame window by
clicking the "Detach" button and resize that frame,
then my component won't grow (different to a button
which would grow). You can see the applet and the
source code at http://pref.dyndns.org/grid/grid.html
And the same applet with a button in place of my own
component is at http://pref.dyndns.org/grid/grid2.html
How could I make my own component to behave same
as buttons and make it grow if there is more space
available? Thank you
Regards
Alex
PS: And yes, I'd like to use offscreen painting
because there will be animations infolved.
What would be the best way to keep the dimensions
of the offscreen Graphics up to date for the
cases when my component will be resized?
A:
Don't override the getPreferredSize().
You can query the size of the component before you repaint it. I think
however that you are going to eventually decide you have to control the
size of your Board more closely. Even if just to maintain its aspect ratio.
I like to use BufferedImage for my offscreen buffer and then draw it to
the Graphics of the component I want it displayed on.
Looking at your code; you will want to make your offscreen image
someplace other than in your paint(). The rendering to the offscreen
image will probably take place in your run(). Also in run you call
repaint() to schedule repainting of the component. Here is a very
simple example. It is missing the stop and start code.
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
public class test extends Applet implements Runnable {
BufferedImage osi;
Random rand;
int width,height;
public void init() {
width = getWidth();
height = getHeight();
osi = new BufferedImage(
width,height,BufferedImage.TYPE_INT_ARGB);
rand = new Random(System.currentTimeMillis());
new Thread(this).start();
}
public void run() {
while (true) {
Graphics g = osi.getGraphics();
g.fillRect(0,0,osi.getWidth(),osi.getHeight());
g.setColor(Color.BLUE);
g.fillOval(rand.nextInt(width),rand.nextInt(height),20,20);
g.dispose();
repaint();
try { Thread.sleep(400); }
catch (InterruptedException ie) { }
}
}
public void paint(Graphics g) {
g.drawImage(osi,0,0,width,height,this);
}
public void update(Graphics g) {
paint(g);
All this talk about games and animation got me hot to write a pong game
again. Are you old enough to remember pong? In the early 70s you would
see them in bars. Mouse button releases the pong and mouse movement
moves the paddle.
http://www.frazmtn.com/~knute/pong.htm
(chuckles) Hands up everyone who has the
thechnology to cross interstellar space!
Sorry Knute, doesn't work here on my OpenBSD -current PC -
neither with Mozilla, nor with Konqueror (java 1.3.1):
Java VM version: 1.3.1-p9
Java VM vendor: Sun Microsystems Inc.
WARNING: Security Manager disabled!
Unable to load JSSE SSL stream handler, https support not available
For more information see http://java.sun.com/products/jsse/
java.lang.ClassNotFoundException:
sun.plugin.security.Broken11ClassFixer
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
at java.lang.ClassLoader.loadClass(ClassLoader.java:253)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:195)
at org.kde.kjas.server.KJASBrokenClassFixer.init(KJASBrokenClassFixer.java:62)
at org.kde.kjas.server.KJASBrokenClassFixer.<init>(KJASBrokenClassFixer.java:30)
at org.kde.kjas.server.KJASAppletClassLoader.fixAndDefineClass(KJASAppletClassLoader.java:368)
at org.kde.kjas.server.KJASAppletClassLoader.loadFixedClass(KJASAppletClassLoader.java:317)
at org.kde.kjas.server.KJASAppletClassLoader.findClass(KJASAppletClassLoader.java:236)
at org.kde.kjas.server.KJASAppletClassLoader.loadClass(KJASAppletClassLoader.java:274)
at org.kde.kjas.server.KJASAppletStub$2.run(KJASAppletStub.java:163)
at java.lang.Thread.run(Thread.java:484)
KJAS: Pong could not be fixed
java.lang.UnsupportedClassVersionError: Pong (Unsupported major.minor
version 48.0)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:486)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:111)
at org.kde.kjas.server.KJASAppletClassLoader.fixAndDefineClass(KJASAppletClassLoader.java:374)
at org.kde.kjas.server.KJASAppletClassLoader.loadFixedClass(KJASAppletClassLoader.java:317)
at org.kde.kjas.server.KJASAppletClassLoader.findClass(KJASAppletClassLoader.java:236)
at org.kde.kjas.server.KJASAppletClassLoader.loadClass(KJASAppletClassLoader.java:274)
at org.kde.kjas.server.KJASAppletStub$2.run(KJASAppletStub.java:163)
at java.lang.Thread.run(Thread.java:484)
Class could not be loaded: Pong
Backtrace:
java.lang.ClassNotFoundException: triggered by
java.lang.UnsupportedClassVersionError: Pong (Unsupported major.minor
version 48.0)
at org.kde.kjas.server.KJASAppletClassLoader.loadFixedClass(KJASAppletClassLoader.java:325)
at org.kde.kjas.server.KJASAppletClassLoader.findClass(KJASAppletClassLoader.java:236)
at org.kde.kjas.server.KJASAppletClassLoader.loadClass(KJASAppletClassLoader.java:274)
at org.kde.kjas.server.KJASAppletStub$2.run(KJASAppletStub.java:163)
at java.lang.Thread.run(Thread.java:484)
OpenBSD is not a popular OS though (yet!), that's true :-)
Regards
Alex
The on-line compiler* is indicating that
Color.GRAY and color.WHITE
were not defined in the 1.3 release.
http://www.physci.org/javac.jsp
Knute, perhaps you should instantiate
the two colors involved. Either that, or
drop the Jave Version Applet into the
page with a target of 1.4.
http://www.physci.org/codes/jre.jsp
I forgot about Color. The statics were lower case until 1.3 or 1.4. I
changed that (Pong version 1.1). There may still be some things in
there that are later than 1.3. Is there any simple way to check? The
docs don't always denote when stuff was added.
It ran on my Red Hat Linux 9 under Gnome but it was jumpy. I've got
mozilla 1.6 in both Windows and Linux. It should run on BSD and I'll
have to try it under KDE just for fun.
Same way I did.
http://www.physci.org/javac.jsp ;-)
It has revealed some quite
interesting things..
>..The
> docs don't always denote when stuff was added.
...that do not agree with the
JavaDocs.
Of course, if you have a 1.3 rt.jar
lying around, you can use the
-bootclasspath option.
I downloaded 1.3.1_09 and redeployed the Pong.jar. It should work in As
BSD machine. I would be curious to know if it doesn't. I made a couple
of changes to make it more playable too.
I'm really disappointed at how it runs on my RH 9. A lot of the
repaints are being combined. I don't know if that is because the
display is so slow compared to Winblows or what.
Hi, yes it works here on OpenBSD with Java 1.3.1 now:
http://pref.dyndns.org/grid/pong.jpg
I've also fixed the resizing problems of my component -
I've overridden setBounds and setSize and create a new
offscreen Image and Graphics there:
http://pref.dyndns.org/grid/Grid.java
To fix the problem that the Applet detached to a Frame
has been always iconified in KDE, I've removed frame.hide()
and just destroy/create that Frame. Now the only problem
left is that attaching a Frame back into Applet at
http://pref.dyndns.org/grid/grid.html
takes long time on Windows (and with frame.hide()) it
wasn't faster. So if anyone has an idea, please tell me.
I've found 2 applets on the web which do detaching/attaching
applets and it works much faster there, wonder why...
http://www.accesscom.com/~lillge/pgc/
http://futureboy.homeip.net/chat/
Regards
Alex