Christopher has posted 9 posts at DZone. You can read more from them at their website. View Full User Profile

DJ NativeSwing - reloaded: JWebBrowser, JFlashPlayer, JVLCPlayer, JHTMLEditor.

03.12.2008
| 44283 views |
  • submit to reddit

 

3. Advanced capabilities

The library takes care of most common integration issues. This covers modal dialog handling, Z-ordering, heavyweight/lightweight mix (to a certain extent), invisible native components with regards to focus handling and threading.

Here are some more screenshots, showing a lightweight/heavyweight mix, and Z-ordering capability:

Component Mix 1

Component Mix 2

The demo application that is part of the distribution shows all the features along with the source code, so check it out!

 

4. Project info and technical notes

Webstart demo: http://djproject.sourceforge.net/ns/DJNativeSwingDemo.jnlp
Screenshots: http://djproject.sourceforge.net/ns/screenshots
Native Swing: http://djproject.sourceforge.net/ns
The DJ Project: http://djproject.sourceforge.net

The 0.9.4 version has a completely new architecture. It still uses SWT under the hood, but it does not use the SWT_AWT bridge anymore.

The JWebBrowser and browser-based components require XULRunner to be installed, except on Windows when using Internet Explorer.
The JVLCPlayer requires VLC to be installed.
The JHTMLEditor uses the FCKeditor.

 

5. Conclusions

This project finally brings all that is needed to make Java on the desktop a reality. A web browser, a flash player, a multimedia player, and even an HTML editor. So, what next?

Yes, what next? For that one, I am waiting for your feedback. So, what do you think? What are your comments and suggestions?

-Christopher

 

References
Published at DZone with permission of its author, Christopher Deckers. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Andrew McVeigh replied on Wed, 2008/03/12 - 8:45am

wow, really good stuff!  just a couple of questions / comments:

1. i notice the sourceforge page says win2k, winxp for the OS.  however, the flash, browser, html editor and (presumably) movie player work fine under my installation of ubuntu linux.  what exactly are the supported platforms?  if only windows, could you potentially expand the list based on the linux results?

 (i'm still investigating why this should be so (!), particularly as the download looks only to have the swt file for windows included.  i must have a reference to the SWT jars in my path or something like that?!)

2. might be an idea to put a more prominent link to the sourceforge summary page in the home page.  took me a while to find it.

Cheers,
Andrew 

Jeff Stano replied on Wed, 2008/03/12 - 8:49am

Wow, just what I was looking for. I'm also looking to integrate Adobe Acrobat Reader in. If you point me in the right direction I can assist in doing the work.

Andrew McVeigh replied on Wed, 2008/03/12 - 9:03am in response to: Andrew McVeigh

(i'm still investigating why this should be so (!), particularly as the download looks only to have the swt file for windows included. i must have a reference to the SWT jars in my path or something like that?!)

 err, whoops.  i just read your page which states it works on linux if xulrunner is installed.

Cheers,
Andrew 

 

Christopher Deckers replied on Wed, 2008/03/12 - 9:07am in response to: Andrew McVeigh

Andrew, 

1. Supported platforms include Windows, Linux, and potentially other platforms where SWT is supported and allows to integrate SWT components in Swing.

Linux was missing because this summary was for DJ Project - Native Integration, which is the first project that I did which was part of the DJ Project. I just added Linux to follow your suggestion. Thanks! 

About the SWT library, the download distribution is already quite big, so I decided to only ship the SWT library for Windows. For Linux, I explain in the readme file to simply place "swt.jar" in the classpath (by default the library looks up for "swt.jar" and falls back to the Windows version).

2. I will see if I should place another Sourceforge Link, or make it more visible.

Thanks a lot for your comments! 

-Christopher

 

Christopher Deckers replied on Wed, 2008/03/12 - 9:12am in response to: Jeff Stano

Jeff,

The Acrobat reader is a great idea! 

Impementation-wise, there are two possibilities:

  1. browser-based, piloted by Javascript (like the Flash player and the VLC player), so you could look into those sources.
  2. Win32 only by using Ole integration (in which case, the Window media player is a good example, but I aslo have a really simple JRealMedia component which is not part of the distribution).

I tend to favor browser-based component whenever possible, because it is cross-platform and handles all the plugin resolution problems.

Feel free to contact me via e-mail if you want to discuss it further.

Thanks!

-Christopher 

Christopher Deckers replied on Wed, 2008/03/12 - 3:32pm in response to: Jeff Stano

Jeff,

I investigated the browser-based approach to the PDF reader, and I have a few conclusions:

  • There are only few methods to act on the plugin that are interesting (show/hide toolbar, set zoom level).
  • These few methods only seem to work when the browser is IE.

Based on these findings, I believe it is not worth creating a new component (JPDFReader or whatever), but achieve the same result with:

JWebBrowser webBrowser = new JWebBrowser();
webBrowser.setBarsVisible(false);
webBrowser.setURL(pdfPathOrURL);

 

-Christopher

Jeff Stano replied on Wed, 2008/03/12 - 8:15pm

Great, I'll give it a try.

Wong Qil replied on Thu, 2008/03/13 - 1:45am in response to: Christopher Deckers

Actually, most MicroSoft office documents(Word, PowerPoint...) will work too, I mean, in IE.

[quote=chrriis]

Jeff,

I investigated the browser-based approach to the PDF reader, and I have a few conclusions:

  • There are only few methods to act on the plugin that are interesting (show/hide toolbar, set zoom level).
  • These few methods only seem to work when the browser is IE.

Based on these findings, I believe it is not worth creating a new component (JPDFReader or whatever), but achieve the same result with:

JWebBrowser webBrowser = new JWebBrowser();
webBrowser.setBarsVisible(false);
webBrowser.setURL(pdfPathOrURL);

 

-Christopher

[/quote]

Rob Blanchard replied on Mon, 2008/03/24 - 2:40pm

I didn't immediately see it, but does JWebBrowser provide any visiblity into reading or writing of cookies, or is that handled by a lower level object?

 This is great work... 0.9.4 is much more stable than previous versions.

Christopher Deckers replied on Mon, 2008/03/24 - 2:59pm in response to: Rob Blanchard

0.9.4 uses a completely different architecture, which was the only way to achieve stability.

About the cookies, it is all handled internally by the Internet Explorer / XULRunner engine, so this is not accessible. On-the-other hand, it is possible to clear all the session cookies of all instances.

 

Rob Blanchard replied on Tue, 2008/03/25 - 9:25pm

What is the proper invocation of the executeAndWaitForCommandResult method that is in the JWebBrowser class?  My motive is that it may be possible to retrieve cookie values by executing JavaScript to assign the document.cookie to a variable.  The return of this assignment should actually be the value of the variable (in other words, the cookies).

 Thanks for any assistance.

Christopher Deckers replied on Wed, 2008/03/26 - 2:06am in response to: Rob Blanchard

executeAndWaitForCommandResult executes some JS code, and expects that code to use the command channel to message back the result.

The API of that particular call has changed between 0.9.4 and the next 0.9.5, so if you want to use the latest version, please contact me by e-mail and I would give you a preview of the 0.9.5 version.

In 0.9.4, you would do something like:

String result = browser.executeAndWaitForCommandResult("getCookies", "sendCommand('getCookies:' + [JS GetCookie code]);");

In 0.9.5, sendCommand accepts parameters. Thus the call becomes:

String result = browser.executeAndWaitForCommandResult("getCookies", "sendCommand('getCookies', [JS GetCookie code]);");

Note that this method can only return a String result.

Don't hesitate to contact me by e-mail in case you have any other questions.

aslan ozturk replied on Sun, 2008/06/08 - 8:52am

Hi all

executeAndWaitForCommandResult executes some JS code, and expects that code to use the command channel to message back the result.

The API of that particular call has changed between 0.9.4 and the next 0.9.5, so if you want to use the latest version, please contact me by e-mail and I would give you a preview of the 0.9.5 version.

ankara evden eve nakliyat 

 

Christopher Deckers replied on Sun, 2008/06/08 - 1:28pm in response to: aslan ozturk

Indeed, I changed the API to make it much simpler.

Before, you had to execute a script that explicitely sends a message using the commnand channel, which meant you had to add a command listener.

Now you have a method that is synchronous and returns the result, without the need to explicitely send a command:
Object JWebBrowser.executeJavascriptWithResult(String javascript).

I believe this is a much cleaner API, that does not ressemble a hack as it was before :)

-Christopher

Keki Bakshi replied on Tue, 2008/06/24 - 12:31am

I want to use DJ Project - Native Swing... to load JFlashPlayer component so that I can run my flex code in a desktop application.

This Swing application is supported on Solaris. Does DJ Project - Native Swing library support Solaris platform? If no, then are there any plans to add support for solaris? 

 

ramesh kancherla replied on Wed, 2008/07/02 - 11:56am in response to: Wong Qil

Hi Chrriis,

           This is rameshkancherla. I am using DJ Native Swing Project. when i am sending url through jWebbrowser.setURL(url); it is working fine. url like http://www.abc.com

But i am getting one problem . when i am sending url with( cookie ) jsessionid then i am not getting response from server. i am getting only session time out.

i am appending cookie as like String url = "http://www.abc.com;JSESSIONID=123456789"

 can you please give me  suggestion  for solving my  problem.

Thanks & Regards

Ramesh K 

 

 

ramesh kancherla replied on Wed, 2008/07/02 - 12:00pm in response to: Wong Qil

Hi Chrriis,

           This is rameshkancherla. I am using DJ Native Swing Project. when i am sending url through jWebbrowser.setURL(url); it is working fine. url like http://www.abc.com

But i am getting one problem . when i am sending url with( cookie ) jsessionid then i am not getting response from server. i am getting only session time out.

i am appending cookie as like String url = "http://www.abc.com;JSESSIONID=123456789"

 can you please give me  suggestion  for solving my  problem.

Thanks & Regards

Ramesh K

ramesh kancherla replied on Wed, 2008/07/02 - 12:06pm

Hi Chrriis,

           This is rameshkancherla. I am using DJ Native Swing Project. when i am sending url through jWebbrowser.setURL(url); it is working fine. url like http://www.abc.com

But i am getting one problem . when i am sending url with( cookie ) jsessionid then i am not getting response from server. i am getting only session time out.

i am appending cookie as like String url = "http://www.abc.com;JSESSIONID=123456789"

 can you please give me  suggestion  for solving my  problem.

Thanks & Regards

Ramesh K

ramesh kancherla replied on Wed, 2008/07/02 - 12:07pm

Hi Chrriis,

           This is rameshkancherla. I am using DJ Native Swing Project. when i am sending url through jWebbrowser.setURL(url); it is working fine. url like http://www.abc.com

But i am getting one problem . when i am sending url with( cookie ) jsessionid then i am not getting response from server. i am getting only session time out.

i am appending cookie as like String url = "http://www.abc.com;JSESSIONID=123456789"

 can you please give me  suggestion  for solving my  problem.

Thanks & Regards

Ramesh K

Christopher Deckers replied on Thu, 2008/07/03 - 12:31am in response to: ramesh kancherla

Hi Ramesh,

DJ NativeSwing uses the SWT browser under the hood, and it does not allow setting cookies...

On the other hand, passing query string parameters is allowed:

http://www.abc.com?JSESSIONID=123456789

but this assumes the server understands that particular parameter. If you control the server, then it might be a solution.

 -Christopher

suresh kumar replied on Thu, 2008/07/17 - 5:39am

Hi Christopher,

   I am new in JAVA Appliction.I used JFlashPlayer,Its working fine.Is it possible to add Keylistner?.I want to exit the JFlashPlayr,if i pressed the ESC Key.

Thanks & Regds,

Suresh

Christopher Deckers replied on Thu, 2008/07/17 - 6:41am in response to: suresh kumar

Hi Suresh,

You could get the underlying component and attach a key listener, but I don't know if they are received so you have to try:

flashPlayer.getWebBrowser().getNativeComponent().addKeyListener(xxx);

A better approach would be to have the Flash application to listen to the key events and send a message to the Java application when it wants to close. Sending a message from a Flash application is shown in the demo. This of course means you have to have control over the Flash application code.

-Christopher

suresh kumar replied on Thu, 2008/07/17 - 7:59am in response to: Christopher Deckers

Thanks.It worked like a charm.

 Suresh

ramesh kancherla replied on Fri, 2008/07/25 - 10:38am in response to: Christopher Deckers

Hi Christopher,

This is Ramesh Kancherla, I am using DJ Native Swing web browser. it is working well when i attempt to use it as single browser. But my requirement is ,i need to show more than one browser screen at a time. if we do this i.e. calling DJ Browser which calls the method runeventpump to open a browser also been used more than once

Then i am getting the *************** Exception. Cant we use the DJ Browser for calling more than once.to show 2 different urls in two screens in my application?

can you please give me suggestion. 

Thanks & Regards

Ramesh K

Christopher Deckers replied on Fri, 2008/07/25 - 12:04pm in response to: ramesh kancherla

Hi Ramesh,

It is hard to tell what the problem is but it should work: I open multiple web browser in different tabs, or on a desktop pane.

The best way for me to help you would be that you send me a simple example with sources by e-mail so that I can test and debug.

Cheers,

-Christopher

ramesh kancherla replied on Sun, 2008/07/27 - 11:54am in response to: Christopher Deckers

Hi Christopher

               I am sending sample code.this code is for one screen. if i am trying to open two screens browsers i am getting error at runeventpump(). can you please give me suggestion.

 

 package browser;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Toolkit;

import javax.swing.SwingUtilities;
import javax.swing.JFrame;

import chrriis.dj.nativeswing.ui.JWebBrowser;
import chrriis.dj.nativeswing.NativeInterfaceHandler;
import chrriis.dj.nativeswing.ui.event.WebBrowserAdapter;
import chrriis.dj.nativeswing.ui.event.WebBrowserEvent;
import chrriis.dj.nativeswing.ui.event.WebBrowserNavigationEvent;
import com.instacoll.livedocuments.oo.configuration.InstaConfig;
import com.instacoll.livedocuments.oo.exception.StringUtils;
import com.instacoll.livedocuments.oo.instasecuremanager.InstaSecureManager;
import com.instacoll.livedocuments.oo.miscellaneous.UserStateManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;
import javax.swing.ImageIcon;

public class AddDocumentProperties extends JFrame {

    private static Runnable xxx;
    final JFrame con = this;
    public static AddDocumentProperties AddDocProp = null;
    private static boolean bThreadStatus = false;
    private static String documentId;
        private String currenturl = "";
    private String prevurl = "";
    JWebBrowser webBrowser;

    public static AddDocumentProperties getInstance() {
        if (AddDocProp == null) {
            AddDocProp = new AddDocumentProperties(documentId);
        }
        return AddDocProp;
    }

    public AddDocumentProperties(String documentID) {
        super("Add Document Properties");
        Class<AddDocumentProperties> clazz = AddDocumentProperties.class;

        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setLocationByPlatform(true);
        String img = InstaConfig.TRAY_ICON_IMAGE;
        img = img.substring(0, img.lastIndexOf("/"));
        setIconImage(new ImageIcon(img + "liveimg.JPG").getImage());

        Container contentPaneF = getContentPane();
        this.setSize(900, 500);

        int x = (Toolkit.getDefaultToolkit().getScreenSize().width - this.getSize().width) / 2;
        int y = (Toolkit.getDefaultToolkit().getScreenSize().height - this.getSize().height) / 2;
        this.setBounds(x, y, this.getSize().width, this.getSize().height);

        webBrowser = new JWebBrowser() {        };
        webBrowser.setMenuBarVisible(false);
        webBrowser.setButtonBarVisible(false);
        webBrowser.setAddressBarVisible(false);
        webBrowser.setStatusBarVisible(false);
//      /instasecure/displayDocumentDetailsPage.do?docId=1230941
//    webBrowser.setURL("http://www.yahoo.com");
//        /instasecure/taskAssignPage.do?docId=1233332
//        GET /instasecure/signAssignPage.do?docId=1233342
        showPage(InstaConfig.APPLICATIONURL + "displayDocumentDetailsPage.do?docId=" + documentID);
//        webBrowser.setURL(InstaConfig.APPLICATIONURL + "displayDocumentDetailsPage.do?docId=" + documentID);
        contentPaneF.add(webBrowser, BorderLayout.CENTER);
        webBrowser.addWebBrowserListener(new WebBrowserAdapter() {

            @Override
            public void commandReceived(WebBrowserEvent e, String command) {
                JWebBrowser web = (JWebBrowser) e.getSource();
                web.getURL();
            }

            @Override
            public void urlChanged(WebBrowserNavigationEvent arg0) {
                String url = arg0.getNewURL();
                if (url.equalsIgnoreCase("about:blank")) {
                } else if (url.contains("http")) {
                    showPage(url);
                } else {
                    if (url.contains("about:blank")) {
                        url = url.substring(11);
                    } else if (url.contains("blank")) {
                        url = url.substring(5);
                    }


                    if (!url.equals("")) {
                        //url = InstaConfig.APPLICATIONURL + url;    
                        url = "http://live.instacoll.com/instasecure/" + url;
                        showPage(url);
                    }

                }
            }
        });
    }

    public AddDocumentProperties() {

    }

    private void showPage(String pageUrl) {

        String inputLine;
        try {
            String cookie = UserStateManager.getInstance().getAuthKey().trim();
            System.out.println(pageUrl);
            prevurl = currenturl;
            currenturl = pageUrl;
            URL url = new URL(pageUrl);
            URLConnection conn = url.openConnection();
            conn = url.openConnection();
            conn.setRequestProperty("Cookie", cookie);
            conn.setRequestProperty("Content-type", "text/html");

            StringBuffer answer1 = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                answer1.append(line);
            }
            reader.close();

//             System.out.print(answer1.toString());
            webBrowser.setText(answer1.toString());
            webBrowser.setVisible(true);

        } catch (Exception ex) {
            InstaSecureManager.logger.log(Level.SEVERE, StringUtils.getStackTrace(ex));
        }
    }
    public void showAddDocProperties(final String docID) {
        documentId = docID;

        if (AddDocProp == null) {
            if (bThreadStatus == false) {
                bThreadStatus = true;
                AddDocProp = new AddDocumentProperties(documentId);
            }
//login.setVisible(true);
            initialise(true);
        } else {
            reinit();
        }
    }

    private static void initialise(boolean bVisible) {
        final boolean bShow = bVisible;
        NativeInterfaceHandler.init();
        Toolkit.getDefaultToolkit().setDynamicLayout(true);
        xxx = new Runnable() {

            public void run() {
                try {
                    javax.swing.UIManager.setLookAndFeel("com.birosoft.liquid.LiquidLookAndFeel");
                    com.birosoft.liquid.LiquidLookAndFeel.setLiquidDecorations(true);
                } catch (Exception e) {

                }
                AddDocProp.setVisible(bShow);
            //login.setAlwaysOnTop(true);
            }
        };

        SwingUtilities.invokeLater(xxx);
            NativeInterfaceHandler.runEventPump();

    }

    private static void reinit() {
        NativeInterfaceHandler.init();
        Toolkit.getDefaultToolkit().setDynamicLayout(true);

        xxx = new Runnable() {

            public void run() {
                try {
                    javax.swing.UIManager.setLookAndFeel("com.birosoft.liquid.LiquidLookAndFeel");
                    com.birosoft.liquid.LiquidLookAndFeel.setLiquidDecorations(true);
                } catch (Exception e) {

                }

                if (bThreadStatus == false) {
                    bThreadStatus = true;
                    AddDocProp = new AddDocumentProperties(documentId);
                }

                AddDocProp.setVisible(true);


            }
        };
        SwingUtilities.invokeLater(xxx);

    }

    public static void main(String[] args) {
        AddDocumentProperties docProp = new AddDocumentProperties();
        docProp.showAddDocProperties("11221");
    }
}

 

 Thanks & Regads

Ramesh K 

ramesh kancherla replied on Tue, 2008/07/29 - 12:11pm

Hi Christopher,

                    This is Ramesh Kancherla. I am using DJ Native Swing web browser. It is working well.

But I  am getting one problem. if I tried to open javascript calendarpopup then browser is displaying empty.

I am not getting calander popup. after i refreshed the browser. my JVM is crashing.

can you please give me sugestion how to solve my problem 

 

Thanks & Regards

Ramesh K 

 

Christopher Deckers replied on Tue, 2008/07/29 - 1:02pm in response to: ramesh kancherla

Hi Ramesh,

Without a proper test case, it is hard for me to help you.

I would recommend you send me an e-mail ( chrriis (at) nextencia (dot) net ) when you face some issues along with a test case when it is possible. E-mails are a better way for me to keep track of this and have a focused discution.

Cheers,
-Christopher

 

Christopher Deckers replied on Tue, 2008/07/29 - 1:08pm in response to: ramesh kancherla

Hi Ramesh,

It seems you are not using the latest version of DJ NativeSwing. Several bugs are fixed and the API is greatly improved, so I suggest you upgrade. Be careful, the API is a bit different: package names have changed, and a few methods have a different name, like NativeInterface.open().

Cheers,
-Christopher

 

puneet dixit replied on Fri, 2008/08/22 - 8:14am

hi

    i  m using linux mandriva 2008.1 and i using dj native jflash player but it shows message that flash plugin is not installed .

    but i have install flash plugin .it still showing same message...

                                  plz help........

  thank you

Comment viewing options

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