The Source for Java Technology Collaboration

Home » java.net Forums » Java Desktop Technologies » Swing & AWT

Thread: Major Issue with AWT & JNI?

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 15 - Last Post: May 2, 2007 10:54 AM by: tdanecito
tdanecito

Posts: 379
Major Issue with AWT & JNI?
Posted: Apr 27, 2007 6:54 PM
  Click to reply to this thread Reply

Hi All,
I have noticed that if a canvas object is embedded in a JPanel which in turn is in a Jinternal frame that using :
1. two instances of JInternalFrame on with a canvas object embedded in a JPanel
2. That getting the windows handle using JNI results in a different window handle each time you reselect the same window!

So the call:
JAWT_Win32DrawingSurfaceInfo* dsiwin = (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo

the dsiwin->hnwd is different each time you get focus when reselecting the same JInternal frame! So if you have focus on JInternalFrame #1 get the window handle of the canvas then select JInternalFrame #2 then go reselect JInternalFrame #1 you get a different windows handle for the same Canvas!

Has anyone seen this type of behavior? Is this expected or a bug?

Thanks,
-Tony

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 27, 2007 7:54 PM   in response to: tdanecito
  Click to reply to this thread Reply

Well,

I ran some more tests and it appears as if the jre is destroying the window tied to the drawing surface of a canvas when reselecting the JInternalFrame. I do not know where to find the source for the core code for awt.

Hopefully someone on the java team here moniotring the forum can comment on this issue. This is a real issue with the JInternalFrames and JNI.

Regards,
-Tony

oleg_sukhodolsky

Posts: 87
Re: Major Issue with AWT & JNI?
Posted: Apr 28, 2007 3:16 AM   in response to: tdanecito
  Click to reply to this thread Reply

Hi Tony,

every time you remove component from its container, AWT destroys its peer, and every time you add a component to some container peer for this component is created.
It looks like changing zorder of JInternalFrames is implemented through removing and adding them back (in correct order). If so, it is expected (from AWT point of view) that you will have different native windows for the same heavyweight (hw) component (Canvas).

From Swing point of view, it is not completely supported to mix both hw and lw (lightweight) components in one toplevel. Though this doesn't mean that we will not try to help you to find a way to workaround this problem, but we will always start with suggestion to not mix two different type of components :)

So, do you really need to have Canvas added to JInternalFrame? Perhaps there is some lw component which will allow you to have the same functionality as you need.

With best regards, Oleg.

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 28, 2007 2:44 PM   in response to: oleg_sukhodolsky
  Click to reply to this thread Reply

Hi Oleg,

I am working with video where the windows handle to the peer is needed. The code I am using from open source uses jni to communicate with it's framework.

The video runs fine when running in the JInternal frame JPanel but when I switch between JInternalFrames then back to the original JInternalFrame that has the JPanel with the awt canvas that the video is being drawn to there is a new window handle associated with the canvas and the old one is invalid and an a WM_DESTROY message is generated by the jre to the windows proc associated with the window tied to the canvas.

Any ideas now that you know what I am trying to do? If you have further ideas it would be appreciated. I am trying to replace Quicktime for java which works with JInternalFrames so I can have something worthy of JavaOne.

Regards,
Tony

Example of what can be done when mixing JNI with AWT with Swing (SUCESSFULLY. As far as I know I am the only one on the planet who has doen this with java):

http://www.myuniportal.com/myuniportal-multi-combo3.jpg

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 29, 2007 11:56 AM   in response to: oleg_sukhodolsky
  Click to reply to this thread Reply

Hi Oleg,

After some more thought I am wondering about the use case I tried to describe and your answer.

Does the container (JInternalFrame) when focus is applied to it iterate through the container objects and reorder them? That seems counter productive since the z-order whas checked when you initally added a cavas object to a JPanel object which in turn was added to the JInternalFrame.

The also happens when you iconize the JInternalFrame and there is a canvas object that was added.

Otherwise, everything works just fine as long as the jre does not decide to destroy windows associated with drawing surfaces for canvases.

Is there a way to stop the JInternalFrame or JDesktopPane from routinely destroying peers for the two use cases I mentioned above? I am willing to try a change and give feedback but need a recomendation from Sun.

Also, where can I find the source code for this? Is not the source code open source for Java now?

Regards,
-Tony

oleg_sukhodolsky

Posts: 87
Re: Major Issue with AWT & JNI?
Posted: Apr 29, 2007 1:22 PM   in response to: tdanecito
  Click to reply to this thread Reply

Hi Tony,

I've debugging the code a little and found that in the first case (selecting internal frame), JDesktopPane changes z-order of this internal frame (Container.setComponentZOrder() is called). And for now this method always remove lightweight container which contains heavyweights and do not try to re-stack them (see Container.isRemoveNotifyNeeded())
So, the problem is (theoretically) fixable, but someone needs to change Container and test this change :)

The second case (iconification of internal frame) the cause of the problem is in DefaultDesktopManger.iconifyFrame(). For some reasons this method remove iconified internal frame, although it may be safe enough to hide it (but I'm not an expert in this area so it is just my assumption).

So, to fix the second problem you could try to set custom desktop manager which will not remove iconified internal frame. For the first you may try to subclass JDesktopPane and override setComponentZOrder() to not remove lightweight container with heavyweight children if you the call doesn't change native container for them (there are may be some problems on this way and you have to use some private API).

Also I'd suggest to file two bugs/rfes about these problems (it is always better to have separate bug for every problem). And, if you want, try to fix them and contribute the fixes to us (see jdk7.dev.java.net for sources and details on how to contribute changes).

Hope this helps to you.

Regards, Oleg.

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 29, 2007 11:58 PM   in response to: oleg_sukhodolsky
  Click to reply to this thread Reply

Hi Oleg,

I tried you suggestion for number 1 and you are correct. Is the JDesktopPane part of this open source project? It would be helpfull if I could see it so I can understand what you are saying better and make my code for the one method setComponentZOrder(). Seems in the JDesktopPane the JInternalFrame is the only thing passed into it so I need to understand what the current JDesktopPane code looks like.

For number 2 regarding a DesktopManager I wrote one that extended DefaultDesktopManager and used setDesktopManager() for the JDesktopPane and the methods never got called. I am working within Eclipse and set the debugger to trigger on inconifyFrame() and minimizeFrame() and neither method got called when selecting the minimize button on a JInternalFrame

Not sure why that is happening but I want to be very sure when I write up the bugs I have the source and the potential fix. So any help appreciated.

Many Thanks,
-Tony

oleg_sukhodolsky

Posts: 87
Re: Major Issue with AWT & JNI?
Posted: Apr 30, 2007 12:44 AM   in response to: tdanecito
  Click to reply to this thread Reply

Hi Tony,

> I tried you suggestion for number 1 and you are
> correct. Is the JDesktopPane part of this open source
> project? It would be helpfull if I could see it so I
> can understand what you are saying better and make my
> code for the one method setComponentZOrder(). Seems
> in the JDesktopPane the JInternalFrame is the only
> thing passed into it so I need to understand what the
> current JDesktopPane code looks like.

https://jdk7.dev.java.net is not an open-source project, but it is a place where you can download sources of JavaSE. So, there you can get sources for Swing and AWT.

> For number 2 regarding a DesktopManager I wrote one
> that extended DefaultDesktopManager and used
> setDesktopManager() for the JDesktopPane and the
> methods never got called. I am working within Eclipse
> and set the debugger to trigger on inconifyFrame()
> and minimizeFrame() and neither method got called
> when selecting the minimize button on a
> JInternalFrame
>
> Not sure why that is happening but I want to be very
> sure when I write up the bugs I have the source and
> the potential fix. So any help appreciated.

Well, since it is hard to understand why the method is not called in you case, I'm providing the test I used to find the places where we do remove Canvas' peer.

<pre>
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyVetoException;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.WindowConstants;

public class internal_frame_failure {
public static void main(String[] args) {
JFrame jframe = new JFrame("mixing test");
JDesktopPane desktop = new JDesktopPane();
jframe.setContentPane(desktop);
JInternalFrame iframe1 = new JInternalFrame("iframe 1");
iframe1.setIconifiable(true);
iframe1.add(new MyCanvas(Color.RED));
iframe1.setBounds(10, 10, 100, 100);
iframe1.setVisible(true);
desktop.add(iframe1);
JInternalFrame iframe2 = new JInternalFrame("iframe 2");
iframe2.setIconifiable(true);
iframe2.add(new MyCanvas(Color.BLUE));
iframe2.setBounds(50, 50, 100, 100);
iframe2.setVisible(true);
desktop.add(iframe2);
try {
iframe2.setSelected(true);
} catch (PropertyVetoException ex) {
ex.printStackTrace();
}
jframe.setSize(300, 300);
jframe.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jframe.setVisible(true);
}

private static final class MyCanvas extends Canvas
{
private final Color background;
public MyCanvas(Color background) {
this.background = background;
setPreferredSize(new Dimension(100, 100));
}

public void paint(Graphics g) {
g.setColor(background);
g.fillRect(0, 0, getWidth(), getHeight());
}

public void addNotify() {
super.addNotify();
System.out.println("addNotify() on " + background);
}

public void removeNotify() {
super.removeNotify();
System.out.println("removeNotify() on " + background);
new Exception().printStackTrace(System.out);
}
}
}
</pre>

Hope this helps you, Oleg.

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 30, 2007 7:03 AM   in response to: oleg_sukhodolsky
  Click to reply to this thread Reply

Many Thanks Oleg!!

I will try this tonight.

Good to see such a fast response on this forum. Makes me a believer in Sun's support of its users.

Regards,
-Tony

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 30, 2007 11:20 AM   in response to: oleg_sukhodolsky
  Click to reply to this thread Reply

Hi Oleg,

I tried your test and the removeNotify() for the canvas was called by the iconifyFrame() of the DefaultDesktopManager.class when doing a remove of the JInternalFrame. I am assuming the removeNotify() causes the canvas peer to be removed thus is important or is an indication the cavas is being remove. Nice trick by the way it helps a lot.

Now I was able to create a DesktopManager class from the current DefaultDesktopManager class and comment out the remove and put a setVisible(false) for the JInternalFrame and do the opposite for deinconify. I was able to add the MyDefaultDesktopManager class with the modified methods but when iconifying the JInternalFrame the method activateFrame was called which in turn called the JInternalFrame.moveToFront which also called removeNotify for the canvas. I commented out that line and the removeNotify() for the canvas was now not called. Of course since the moveToFront was not called I expect that may be an issue.

I also tried dragging the remaining window and got:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalAccessError: tried to access method javax.swing.JComponent.safelyGetGraphics(Ljava/awt/Component;)Ljava/awt/Graphics; from class javax.swing.MyDefaultDesktopManager
at javax.swing.MyDefaultDesktopManager.beginDraggingFrame(MyDefaultDesktopManager.java:286)
at javax.swing.plaf.basic.BasicInternalFrameUI$BorderListener.mousePressed(BasicInternalFrameUI.java:713)

I saw that for some other methods. Not sure why I get that.

Any ideas appreciated regarding the IllegalAccessError?


Thanks,
-Tony

oleg_sukhodolsky

Posts: 87
Re: Major Issue with AWT & JNI?
Posted: Apr 30, 2007 11:57 AM   in response to: tdanecito
  Click to reply to this thread Reply

Hi Tony,

I have just a basic knowledge about JInternalFrame (I'm not a Swing engineer) and so I can not answer your question about the exception :( Hope someone from Swing team will do this.

Regards, Oleg.

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 30, 2007 1:59 PM   in response to: oleg_sukhodolsky
  Click to reply to this thread Reply

Hey Oleg you get a "A+" for effort.

I will do some googling or Yahooing perhaps I will get lucky and find a reference to it.

Thanks,
-Tony

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: May 1, 2007 1:07 AM   in response to: oleg_sukhodolsky
  Click to reply to this thread Reply

Hi Oleg,

I was able to resolve the issue for iconifyFrame now just the one left.

The moveToFront or zorder issue. I tried to create my own container but very complex issues involved. In the end I was prohibited from creating a container class in java.awt package.

I wonder if leouser is still around? He could whip this out very quickly. Figureing out how to keep heavyweight components from being removed from the container when setting a component to the front probably very easy.

Regards,
Tony in Idaho...

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: Apr 29, 2007 7:07 PM   in response to: tdanecito
  Click to reply to this thread Reply

Hi Oleg,

Thanks very much for looking into this. I will look at this tonight and override the methods you suggested and file a bug report for each separately.

Great Job!
-Tony

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: May 1, 2007 12:33 PM   in response to: tdanecito
  Click to reply to this thread Reply

Okay I filed two bug reports with Sun.

Could really use some advice from an Sun swing person as Oleg mentioned could help me.

Thanks,
-Tony

tdanecito

Posts: 379
Re: Major Issue with AWT & JNI?
Posted: May 2, 2007 10:54 AM   in response to: tdanecito
  Click to reply to this thread Reply

Just an FYI,

Sun has sent notification that the issues regarding inconize and moveToFront are now officially listed as bugs and will show up in the bug database in a few days.

Regards,
-Tony




 XML java.net RSS