Skip to main content

java.awt.Container 's validate method not working with NULL layout

13 replies [Last post]
rfr
Offline
Joined: 2005-04-15
Points: 0

Hi again everyone.

I did an application, that sets null layout to the root container, to work with images at this container. After that i've noticed some problems with the "VALIDATE" method of the class java.awt.Container:

1. In my application I create some new containers and add images to them. The first thing i've noticed is that the container keeps the 0,0,0,0 bounds. I always have to set its bounds to the image bound. But i don't think thats a problem at all. The problem is that if I call the "setBounds" method before adding this new Container to the root container, It will not show the image, even if I call the "validate" method at the rootContainer after all these steps.

2. Ok, my image is on the screen. Now, after a few seconds, I need to remove it. So I call the remove method at the parent container of this new container created for the image and call "validate" at the rootContainer and nothing happens too. The image is still there.

3. In these 2 cases that I've mentioned, if i click in another window of my desktop an click back at the cvm window, the screen seems to refresh and I get the expected final result.

After checking your last build at the SVN, I think the problem might envolve the fact that I'm using NULL LAYOUT.

Can you help me?

Message was edited by: rfr

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Hinkmond Wong

Hi rjr,

phonemeadvanced@mobileandembedded.org wrote:
> Hi again everyone.
>
>
> I did an application, that sets null layout to the root container, to work with images at this container. After that i've noticed some problems with the "VALIDATE" method of the class java.awt.Container:
>
> 1. In my application I create some new containers and add images to them. The first thing i've noticed is that the container keeps the 0,0,0,0 bounds. I always have to set its bounds to the image bound. But i don't think thats a problem at all. The problem is that if I call the "setBounds" method before adding this new Container to the root container, It will not show the image, even if I call the "validate" method at the rootContainer after all these steps.
>
> 2. Ok my image is at the screen. Now after a few seconds I need to remove this. So I call the remove method at the parent container of this new container created for the image and call "validate" at the rootContainer and nothing happens too. The image is still there.
>
> 3. In these 2 cases that I've mentioned, if i click in an other window of my desktop an click back at the cvm window, the screen seems to refresh and I get the expected final result.
>
>
> After checking your last build at the SVN, I think the problem might envolve the fact that I'm using NULL LAYOUT.
>
> Can you help me?
>

It's hard to comment specifically on your problem without seeing your
Java source code of your application. In general, the tricky part about
using images in Java is that you should be using a Canvas object to
paint() the image, then add that Canvas object to a Container, like a
Frame. You do not really want to "add images to [a Container object]"
as you say in #1. If you do you will have painting problems like in
your #2 & #3.

Please see this sample Java source code below that paints images in a
Canvas object which is added to a Container (Frame):

http://www.rgagnon.com/javadetails/java-0229.html

Note that you can change this sample code a bit by making the Container
fit your image. Something like this:

static Image image;
...

frame.resize(image.getWidth(null),image.getHeight(null));

There is also the issue of double-buffering to reduce flicker, but
that's a topic for a different thread. You might want to see this URL
for more info:

http://www.realapplets.com/tutorial/DoubleBuffering.html

Hinkmond

---------------------------------------------------------------------
To unsubscribe, e-mail: advanced-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: advanced-help@phoneme.dev.java.net

rfr
Offline
Joined: 2005-04-15
Points: 0

My code is somthing like the following:

-------
public class TesterXlet implements Xlet {
private Container rootContainer;
private SIManager siManager;

public void destroyXlet(boolean arg0) throws XletStateChangeException {
// TODO Auto-generated method stub

}

public void initXlet(XletContext context) throws XletStateChangeException {
rootContainer = TVContainer.getRootContainer(context);
//rootContainer.setLayout(new GridLayout(0, 1));
rootContainer.setLayout(null);
rootContainer.setSize(new Dimension(640, 480));
rootContainer.setVisible(true);

siManager = SIManager.createInstance();

}

public void pauseXlet() {
// TODO Auto-generated method stub

}

public void startXlet() throws XletStateChangeException {
DvbLocator pictureLocator;
try {
pictureLocator = new DvbLocator("dvb://2.8428.8438");
} catch (InvalidLocatorException e) {
System.out.println("Could not bind the DVB Locator for the libraries.");
throw new XletStateChangeException();
}
ServiceDomain domain = new ServiceDomain();
try {
domain.attach(pictureLocator);
} catch (MPEGDeliveryException e) {
e.printStackTrace();
throw new XletStateChangeException();
} catch (DSMCCException e) {
e.printStackTrace();
throw new XletStateChangeException();
} catch (InterruptedIOException e) {
e.printStackTrace();
throw new XletStateChangeException();
}
DSMCCObject dsmcc = new DSMCCObject(domain.getMountPoint(),"ncl/coisadepele/img/logo.jpg");

Image image = rootContainer.getToolkit().createImage(dsmcc.getURL());

StaticIcon container = new StaticIcon(image);

System.out.println("imageIcon: X-"+container.getX()+"; Y-"
+container.getY()+"; W-"+container.getWidth()+"; H-"
+container.getHeight());

rootContainer.add(container);
container.setBounds(0,0,container.getPreferredSize().width,
container.getPreferredSize().height);
container.setVisible(true);
container.validate();

System.out.println("imageIcon: X-"+container.getX()+"; Y-"
+container.getY()+"; W-"+container.getWidth()+"; H-"
+container.getHeight());

HStaticText text = new HStaticText("This is a real test!!!!");

rootContainer.add(text);
text.setBounds(100, 100, 300, 100);
text.setVisible(true);

rootContainer.validate();

try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
rootContainer.remove(container);
System.out.println("Image removed");
rootContainer.validate();
}

public class StaticIcon extends Container {
private Image image;
private BufferedImage bufferedImage;
private boolean painted;
private Dimension preferredSize = null;

/**
* HF_ImagePanel constructor comment.
*/
public StaticIcon(Image image) {
super();
painted=false;

MediaTracker tracker;

this.image = image;
tracker = new MediaTracker(this);
tracker.addImage(image, 0);
try {
tracker.waitForID(0);
}
catch (InterruptedException e) {
}

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
int w = image.getWidth(this);
int h = image.getHeight(this);
bufferedImage = gc.createCompatibleImage(w, h);
while (bufferedImage == null) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {}
}
Graphics big = bufferedImage.getGraphics();
big.setColor(Color.RED);
big.fillRect(0, 0, w, h);
big.drawImage(image, 0, 0, w, h, 0, 0, w, h, this);
}
public Image getImage() {
return image;
}

public Dimension getPreferredSize(){
if(preferredSize==null){
// preferredSize = new Dimension(bufferedImage.getHeight(),bufferedImage.getWidth());
}
return new Dimension(bufferedImage.getHeight(),bufferedImage.getWidth());
}

public Dimension getMinimumSize(){
return getPreferredSize();
}

public Dimension getMaximumSize(){
return new Dimension(Integer.MAX_VALUE,Integer.MIN_VALUE);
}

public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
if(!painted){
System.out.println("PAinted");
painted=true;
}
}
}
}
---------------

If I put the line "container.setBounds(0,0,container.getPreferredSize().width,container.getPreferredSize().height);" before the line "rootContainer.add(container);" I catch the issue #2;

And after the Thread.sleep(2000), a catch the issue #3.

Here In my example i used an Xlet. Consider the DSMCCObject class as an extension of the java.io.File class. Just replace it.

Hinkmond Wong

Hi rjr,

Without analyzing your source code line-by-line (wouldn't be the right
place on this forum), in general you might want to try a few things:

1. Change the subclass of StaticIcon from Container to Canvas (your
purpose of StaticIcon is not really a container of other UI widgets, but
you want it to paint an image instead)
From this:
> public class StaticIcon extends Container {
To this:
> public class StaticIcon extends Canvas {

2. Use your rootContainer (not container) to set your width and height
From this:
> container.setBounds(0,0,container.getPreferredSize().width,
> container.getPreferredSize().height);
To this:
> rootContainer.setBounds(0,0,image.getWidth(null),
> image.getHeight(null));

Something along the lines of the above changes may help you get rid of
the side-effects you are seeing in your #2 and #3.

Hinkmond

phonemeadvanced@mobileandembedded.org wrote:
> My code is somthing like the following:
>
> -------
> public class TesterXlet implements Xlet {
> private Container rootContainer;
> private SIManager siManager;
>
> public void destroyXlet(boolean arg0) throws XletStateChangeException {
> // TODO Auto-generated method stub
>
> }
>
> public void initXlet(XletContext context) throws XletStateChangeException {
> rootContainer = TVContainer.getRootContainer(context);
> //rootContainer.setLayout(new GridLayout(0, 1));
> rootContainer.setLayout(null);
> rootContainer.setSize(new Dimension(640, 480));
> rootContainer.setVisible(true);
>
> siManager = SIManager.createInstance();
>
> }
>
> public void pauseXlet() {
> // TODO Auto-generated method stub
>
> }
>
> public void startXlet() throws XletStateChangeException {
> DvbLocator pictureLocator;
> try {
> pictureLocator = new DvbLocator("dvb://2.8428.8438");
> } catch (InvalidLocatorException e) {
> System.out.println("Could not bind the DVB Locator for the libraries.");
> throw new XletStateChangeException();
> }
> ServiceDomain domain = new ServiceDomain();
> try {
> domain.attach(pictureLocator);
> } catch (MPEGDeliveryException e) {
> e.printStackTrace();
> throw new XletStateChangeException();
> } catch (DSMCCException e) {
> e.printStackTrace();
> throw new XletStateChangeException();
> } catch (InterruptedIOException e) {
> e.printStackTrace();
> throw new XletStateChangeException();
> }
> DSMCCObject dsmcc = new DSMCCObject(domain.getMountPoint(),"ncl/coisadepele/img/logo.jpg");
>
> Image image = rootContainer.getToolkit().createImage(dsmcc.getURL());
>
> StaticIcon container = new StaticIcon(image);
>
> System.out.println("imageIcon: X-"+container.getX()+"; Y-"
> +container.getY()+"; W-"+container.getWidth()+"; H-"
> +container.getHeight());
>
>
> rootContainer.add(container);
> container.setBounds(0,0,container.getPreferredSize().width,
> container.getPreferredSize().height);
> container.setVisible(true);
> container.validate();
>
> System.out.println("imageIcon: X-"+container.getX()+"; Y-"
> +container.getY()+"; W-"+container.getWidth()+"; H-"
> +container.getHeight());
>
> HStaticText text = new HStaticText("This is a real test!!!!");
>
> rootContainer.add(text);
> text.setBounds(100, 100, 300, 100);
> text.setVisible(true);
>
> rootContainer.validate();
>
> try {
> Thread.sleep(2500);
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> rootContainer.remove(container);
> System.out.println("Image removed");
> rootContainer.validate();
> }
>
> public class StaticIcon extends Container {
> private Image image;
> private BufferedImage bufferedImage;
> private boolean painted;
> private Dimension preferredSize = null;
>
> /**
> * HF_ImagePanel constructor comment.
> */
> public StaticIcon(Image image) {
> super();
> painted=false;
>
> MediaTracker tracker;
>
> this.image = image;
> tracker = new MediaTracker(this);
> tracker.addImage(image, 0);
> try {
> tracker.waitForID(0);
> }
> catch (InterruptedException e) {
> }
>
> GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
> GraphicsDevice gd = ge.getDefaultScreenDevice();
> GraphicsConfiguration gc = gd.getDefaultConfiguration();
> int w = image.getWidth(this);
> int h = image.getHeight(this);
> bufferedImage = gc.createCompatibleImage(w, h);
> while (bufferedImage == null) {
> try {
> Thread.sleep(100);
> } catch (InterruptedException ie) {}
> }
> Graphics big = bufferedImage.getGraphics();
> big.setColor(Color.RED);
> big.fillRect(0, 0, w, h);
> big.drawImage(image, 0, 0, w, h, 0, 0, w, h, this);
> }
> public Image getImage() {
> return image;
> }
>
> public Dimension getPreferredSize(){
> if(preferredSize==null){
> // preferredSize = new Dimension(bufferedImage.getHeight(),bufferedImage.getWidth());
> }
> return new Dimension(bufferedImage.getHeight(),bufferedImage.getWidth());
> }
>
> public Dimension getMinimumSize(){
> return getPreferredSize();
> }
>
> public Dimension getMaximumSize(){
> return new Dimension(Integer.MAX_VALUE,Integer.MIN_VALUE);
> }
>
> public void paint(Graphics g) {
> super.paint(g);
> g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
> if(!painted){
> System.out.println("PAinted");
> painted=true;
> }
> }
> }
> }
> ---------------
>
> If I put the line "container.setBounds(0,0,container.getPreferredSize().width,container.getPreferredSize().height);" before the line "rootContainer.add(container);" I catch the issue #2;
>
> And after the Thread.sleep(2000), a catch the issue #3.
>
> Here In my example i used an Xlet. Consider the DSMCCObject class as an extension of the java.io.File class. Just replace it.
> [Message sent by forum member 'rfr' (rfr)]
>
> http://forums.java.net/jive/thread.jspa?messageID=209083

---------------------------------------------------------------------
To unsubscribe, e-mail: advanced-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: advanced-help@phoneme.dev.java.net

rfr
Offline
Joined: 2005-04-15
Points: 0

Hi Hinkmond,

First of all, thank you so much for your attention.
Unfortunately I can't use Canvas because I'm Personal Basis Profile, and, about the image height and width: the program is getting them correctly, there were some prints at the code to show it, I still think that there is a problem at the validate method when using NULL layout. Can I report this as a BUG?

Hinkmond Wong

phonemeadvanced@mobileandembedded.org wrote:
> Hi Hinkmond,
>
> First of all, thank you so much for your attention.
> Unfortunately I can't use Canvas because I'm Personal Basis Profile,
> and, about the image height and width: the program is getting them
> correctly, there were some prints at the code to show it, I still think
> that there is a problem at the validate method when using NULL layout.
> Can I report this as a BUG?

My fault. Please try using java.awt.Component instead of Canvas (I
should have realized you were using PBP, not PP) from which to extend
StaticIcon.

Let me know if using Component instead of Container as your parent class
of StaticIcon helps you.

The problem with validate looks like it is a problem with a Container
object inside another Container object (Ex. your container is added to
rootContainer, which confuses the layout) and does not look like a bug
to me.

Instead, if StaticIcon extends Component, you will have a Component
properly inside a Container instead of a Container in a Container and it
should then validate correctly using the default Layout at that point.

Hopefully this will help,

Hinkmond

---------------------------------------------------------------------
To unsubscribe, e-mail: advanced-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: advanced-help@phoneme.dev.java.net

rfr
Offline
Joined: 2005-04-15
Points: 0

Hi Hinkmond,

> phonemeadvanced@mobileandembedded.org wrote:
>
> My fault. Please try using java.awt.Component
> instead of Canvas (I
> should have realized you were using PBP, not PP) from
> which to extend
> StaticIcon.

No problem, relax. It's me who should be thankful for your attention. I must say also that i using JavaTV (javatv1.1_01)

> Let me know if using Component instead of Container
> as your parent class
> of StaticIcon helps you.
>
> The problem with validate looks like it is a problem
> with a Container
> object inside another Container object (Ex. your
> container is added to
> rootContainer, which confuses the layout) and does
> not look like a bug
> to me.
>
> Instead, if StaticIcon extends Component, you will
> have a Component
> properly inside a Container instead of a Container in
> a Container and it
> should then validate correctly using the default
> Layout at that point.

Well, actually there where 2 containers, the image (with StaticIcon) and another with some text. To avoid doubts I let the text out of the code and let in just the StaticIcon extending "java.awt.Component" just as you sad. But again it hasn't worked.

Thanks,

Rafael

Hinkmond Wong

Hi Rafael,

phonemeadvanced@mobileandembedded.org wrote:
> Let me know if using Component instead of Container
> as your parent class
> of StaticIcon helps you.
>
> The problem with validate looks like it is a problem
> with a Container
> object inside another Container object (Ex. your
> container is added to
> rootContainer, which confuses the layout) and does
> not look like a bug
> to me.
>
> Instead, if StaticIcon extends Component, you will
> have a Component
> properly inside a Container instead of a Container in
> a Container and it
> should then validate correctly using the default
> Layout at that point.
>
>
> Well, actually there where 2 containers, the image (with StaticIcon) and another with some text. To avoid doubts I let the text out of the code and let in just the StaticIcon extending "java.awt.Component" just as you sad. But again it hasn't worked.
>

Just out of curiosity, what happens when you change these lines

From this:
rootContainer.add(container);
...
rootContainer.add(text);

To this:
import java.awt.BorderLayout;
...
rootContainer.setLayout(new BorderLayout();
rootContainer.add(container, BorderLayout.CENTER);
...
rootContainer.add(text, BorderLayout.BOTTOM);

Any difference at all?

Hinkmond

---------------------------------------------------------------------
To unsubscribe, e-mail: advanced-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: advanced-help@phoneme.dev.java.net

rfr
Offline
Joined: 2005-04-15
Points: 0

Hi Hinkmond,

Sorry for taking so long to answer you.

I did the modifications that you asked me to and it hasn't made any difference at all.

Rafael

rfr
Offline
Joined: 2005-04-15
Points: 0

Any clue?

Hinkmond Wong

Hi Rafael,

phonemeadvanced@mobileandembedded.org wrote:
> Any clue?
>

Looks like you have found a real bug that exists only in the Personal
Basis 1.1 code (including the phoneME Advanced stack). I checked
Personal Basis 1.0 (ported on Microwindows) and your bug does not exist
there, only in Personal Basis 1.1 and above.

Do you want me to enter it into our project IssueTracker as a bug, or do
you want to do it?

See:
https://phoneme.dev.java.net/servlets/ProjectIssues
(Log in using your java.net username and password)

For now, I can only recommend a hack workaround:

- Implement the Runnable interface in your Xlet:
import java.lang.Runnable;

public class TesterXlet implements Xlet, Runnable {
^^^^^^^^

- Add the Runnable interface run() method to do graphics refreshing
(NOTE: you have to move container to be a class variable):

public void run() {
while (true) {
container.repaint();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

- In startXlet, add the start of a graphics refresh thread at the very
end of the existing method (after the rootContainer().validate(); method
call)

public void startXlet() {
Thread graphicsRefreshThread = new Thread(this);
graphicsRefreshThread.start();
}

The above hack workaround should at least mimic a refresh loop for you
so that you can see your image paint correctly when you expose your
window after it is covered, and if you change the container, for example
removing the image.

Hinkmond

---------------------------------------------------------------------
To unsubscribe, e-mail: advanced-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: advanced-help@phoneme.dev.java.net

rfr
Offline
Joined: 2005-04-15
Points: 0

Thanks. but the image is not being removed yet. Instead, your hacking solved another problem, just like you said at PB profile: the window was not being refreshed after positioning another program window over it;texts, images, everything was disappearing even if they were not removed from container. This bug does not exists on Personal profile.

Now the behavior I'm getting at Personal and Basis profile are the following:

-P Basis: After removing the image and validating the container, the image is just disappearing when I grab other desktop window and pass over cvm window.

-Personal: The image just disappears when I click out of the window and then click back

Can I report this bug?

Hinkmond Wong

Hi Rafael,

Yes please go ahead and report the bug at:

https://www.dev.java.net/servlets/TLogin?detour=https://phoneme.dev.java...
(Make sure to log in first)

If you really want to continue down the path of using the hack for now,
instead of removing the image, just create an image file with just all
the background color in it (like a rectangle that is all white).

Ex.
ncl/coisadepele/img/blank.jpg
(All white JPEG image file)

Then, add a new setImage() method to your StaticIcon class:
...
public void setImage(Image newImage) {
this.image = newImage;
}
...

And call container.setImage(blankImage) when you want to remove the logo
image.

Yes, the above is very hacky, :-( but can be a workaround you can use
until someone can make the fix to the bug you are reporting.

Hinkmond

phonemeadvanced@mobileandembedded.org wrote:
> Thanks. but the image is not being removed yet. Instead, your hacking solved another problem, just like you said at PB profile: the window was not being refreshed after positioning another program window over it;texts, images, everything was disappearing even if they were not removed from container. This bug does not exists on Personal profile.
>
> Now the behavior I'm getting at Personal and Basis profile are the following:
>
> -P Basis: After removing the image and validating the container, the image is just disappearing when I grab other desktop window and pass over cvm window.
>
> -Personal: The image just disappears when I click out of the window and then click back
>
> Can I report this bug?
> [Message sent by forum member 'rfr' (rfr)]
>
> http://forums.java.net/jive/thread.jspa?messageID=212626
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: advanced-unsubscribe@phoneme.dev.java.net
> For additional commands, e-mail: advanced-help@phoneme.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: advanced-unsubscribe@phoneme.dev.java.net
For additional commands, e-mail: advanced-help@phoneme.dev.java.net

rfr
Offline
Joined: 2005-04-15
Points: 0

Thanks for the advices!
I will report the bug and also try to fix it. I can't promise anything because I am finishing my MSc and very busy right now.

Thanks for everything,

Rafael