Lobo Project Blog

Primarily about the Lobo web browser and the Cobra rendering engine

Lobo Integration in DeepaMehta

Posted by lobochief on October 21, 2009

DeepaMehta is a collaborative Knowledge Management platform that is GPL licensed.

The latest post of the DeepaMehta blog tells us that the Lobo browser has been integrated with it. If you’re interested in looking at the source code of an integration of the Lobo API, open source projects like DeepaMehta should be helpful.

Posted in lobo | Tagged: | 3 Comments »

Lobo Browser 0.98.4 Released

Posted by lobochief on January 19, 2009

We’re pleased to announce the release of version 0.98.4 of our all-Java web browser: Lobo. The main purpose of this release is to update Lobo’s support of  direct rendering of JavaFX source code, such that it is up to date with JavaFX 1.0.

In the updated default home page for the browser, you will find a new managed-store-demoJavaFX example. I’m posting a screenshot to your right. It’s not a very complicated example, and it is there simply to illustrate some JavaFX and Lobo features. JavaFX code in Lobo has access to the Lobo platform API. The example shows how you can use the managed stores feature of Lobo to securely persist the position of an internal draggable window in a client-side file, as well as the URL of a mini-browser (a scaled Lobo browser frame really) contained within the internal window.

We don’t currently hava a JavaFX-based API for Lobo, only a Java-based one. But we obviously intend to build one in the future.

If you use the example enough, you’ll encounter a couple obvious JavaFX bugs. I have already reproduced the issues outside of Lobo and reported them.

Additionally, we implemented a frequently requested feature: The ability to obtain the document object in a FramePanel or BrowserPanel. Lobo abstracts away the rendering engine, so the document object depends on the content being rendered and the plugin that handles the content.  Look for the getContentObject() method. Also take a look at the new vetoable navigation listeners feature. Navigation events provide the link element if navigation results from a click.

We also managed to squeeze in a few improvements to our pure Java HTML rendering engine and parser: Cobra. Parent (>) and sibling (+) selectors have been implemented. Margin collapsing was implemented as well. It is now possible to control the body margin and overflow settings. Finally, there was a significant refactoring of the layout engine, including a major performance optimization.

Several patches submitted by users of Cobra and Lobo were applied to this version, probably more so than in any prior version. We appreciate these contributions. Please keep them coming. It’s easy to set up a workspace to run Lobo from source and submit patches, particularly if you’re using an IDE like Eclipse.

Please see the changelog for additional details.

Posted in cobra, javafx, lobo, release | Tagged: , | 7 Comments »

JavaFX Video in a Swing Application – Technically Doable

Posted by lobochief on December 29, 2008

There has already been some discussion on how you can embed a JavaFX scene object in a Swing application (see Josh Marinacci’s post). There has also been some discussion on how to write video playback code in JavaFX (see here and here).

What I wanted to find out is what it would take to play JavaFX video in a standalone Swing application. I mean technically. I won’t get into the legal aspects (discussed previously) in this post.

Figuring out which JAR files you need is not difficult to guess. The main difficulty involves the fact that various native DLLs are needed. Instead of trying to guess what the javafx startup program does differently to java, I decided to have a JavaFX program tell me, by printing properties java.class.path and java.library.path.

The java.library.path property value is not lengthy in Windows, and it is exactly what I would’ve expected.

C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop

Now take a look at java.class.path.

C:\Program  Files\JavaFX\javafx-sdk1.0\bin\..\lib\shared\javafxrt.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\eula.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\Decora-SSE.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\Decora-D3D.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\Decora-HW.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\Decora-OGL.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\Scenario.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\gluegen-rt.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\javafx-swing.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\javafxgui.jar;C:\Progr
amFiles\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\jmc.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\jogl.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\websvc.jar;C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop\script-api.jar;.;

Well, not all of those are probably needed in any given program, but I’d include all of those just so there are no differences with the javafx launcher.

So now we know how we need to run the standalone Swing application.

java -Djava.library.path=”C:\Program Files\JavaFX\javafx-sdk1.0\bin\..\lib\desktop” -cp “… humongous classpath …” javafx_tests.FXVideoPlayer

I’ve also confirmed that if you copy the DLL files to a different directory and point java.library.path to it, that also works.

We just need to write the code. What I did is come up with a FXVideoPlayer class, a Swing component. It takes a source URL and has a play() method. Its source code follows.


import javax.swing.*;
import java.awt.*;
import javafx.scene.media.*;
import javafx.scene.*;
import javafx.reflect.*;

import com.sun.javafx.runtime.TypeInfo;
import com.sun.javafx.runtime.sequence.*;
import com.sun.scenario.scenegraph.fx.*;
import com.sun.scenario.scenegraph.*;

public class FXVideoPlayer extends JPanel {
    private static final FXClassType PANEL_SCENE_TYPE;
    private final FXObjectValue fxMedia;
    private final FXClassType mediaType;
    private final FXObjectValue fxMediaPlayer;
    private final FXClassType mediaPlayerType;

    static {
        String helperName = "com.sun.javafx.scene.JSGPanelSceneImpl";
        FXClassType type = FXContext.getInstance().findClass(helperName);
        PANEL_SCENE_TYPE = type;
    }

    public FXVideoPlayer(String source) {
        Media media = new Media();
        // Some crazy JavaFX reflection here to get a Media object we can use.
        FXClassType mediaType = FXContext.getInstance().findClass(
                Media.class.getName());
        FXObjectValue fxMedia = mediaType.allocate();
        fxMedia.initVar("source", FXLocal.getContext().mirrorOf(source));
        fxMedia.initialize();
        this.fxMedia = fxMedia;
        this.mediaType = mediaType;
        // Same here to set MediaPlayer.media.
        FXClassType mediaPlayerType = FXContext.getInstance().findClass(
                MediaPlayer.class.getName());
        FXObjectValue fxMediaPlayer = mediaPlayerType.allocate();
        fxMediaPlayer.initVar("media", fxMedia);
        fxMediaPlayer.initialize();
        this.fxMediaPlayer = fxMediaPlayer;
        this.mediaPlayerType = mediaPlayerType;
        // And now we set MediaView.mediaPlayer
        FXClassType mediaViewType = FXContext.getInstance().findClass(
                MediaView.class.getName());
        FXObjectValue fxMediaView = mediaViewType.allocate();
        fxMediaView.initVar("mediaPlayer", fxMediaPlayer);
        fxMediaView.initialize();
        MediaView mediaView = (MediaView) ((FXLocal.ObjectValue) fxMediaView)
                .asObject();
        // Finally, let's create a scene!
        FXClassType sceneType = FXContext.getInstance().findClass(
                Scene.class.getName());
        FXObjectValue fxScene = sceneType.allocate();
        Sequence contentSequence = Sequences.make(TypeInfo
                .makeTypeInfo(mediaView), new MediaView[] { mediaView });
        fxScene.initVar("content", FXLocal.getContext().mirrorOf(
                contentSequence));
        fxScene.initialize();
        FXClassType type = PANEL_SCENE_TYPE;
        if (type == null) {
            throw new IllegalStateException("JSGPanelSceneImpl type not set.");
        }
        FXObjectValue panelSceneImpl = type.allocate();
        panelSceneImpl.initVar("scene", fxScene);
        panelSceneImpl.initialize();
        FXValue jsgPanelV = type.getVariable("jsgPanel").getValue(
                panelSceneImpl);
        JComponent sceneComponent = (JComponent) ((FXLocal.ObjectValue) jsgPanelV)
                .asObject();

        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(100, 100));
        this.setBackground(Color.GREEN);
        this.add(BorderLayout.CENTER, sceneComponent);
    }

    public void play() {
        this.mediaPlayerType.getFunction("play").invoke(this.fxMediaPlayer);
    }

    /* Entry point for testing below */

    private static final String MEDIA_LOCATION = "http://sun.edgeboss.net/download/sun/media/1460825906/1460825906_2956241001_big-buck-bunny-640x360.flv";

    public static void main(String[] arg) {
        System.out.println("java.library.path="
                + System.getProperty("java.library.path"));
        System.out.println("java.class.path="
                + System.getProperty("java.class.path"));
        final FXVideoPlayer player = new FXVideoPlayer(MEDIA_LOCATION);
        JFrame window = new JFrame("FX View Player Test");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLayout(new BorderLayout());
        window.add(BorderLayout.CENTER, player);
        window.setSize(new Dimension(700, 500));
        window.setVisible(true);

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                player.play();
            }
        });
    }
}

The JavaFX reflection code can get complicated, but hey, it works. It’s basically the same methodology you’d use to embed a Scene as explained by Josh Marinacci.

Of course, you could write much of the above in JavaFX and have a thiner layer in Swing, but where’s the fun in that?

Posted in javafx | Tagged: | 4 Comments »

Like Cobra? Also in need of work?

Posted by lobochief on December 23, 2008

This was a bit surprising. There’s a job ad at odesk.com that lists Cobra as one of its requirements.

The developer must also know how to parse and modify an HTML/CSS file programtically using Cobra (http://lobobrowser.org/cobra.jsp).

Man, Cobra has been gaining exposure, but I didn’t think it was getting listed as a job requirement.

There you go. I bet it’s not that easy to find qualified applicants for that job.

Disclaimer – I’m not associated in any way with the company that posted the ad. It’s just something that popped up.

Posted in cobra | Tagged: , | Leave a Comment »

The JavaFX 1.0 License – Completely unreasonable?

Posted by lobochief on December 22, 2008

We’re kicking off a brand new blog today, as you can see, and to do this I thought I’d discuss the JavaFX 1.0 license. There was some chatter about this back in August, but this was prior to the release of JavaFX 1.0. (See posts by Mark J. Wielaard and Anthony Goubard). The license was supposed to be early stage, and so on.

Of course, one of the key parts of the Lobo Project is its direct rendering of JavaFX. We believe that eventually HTML should be considered just one web language in a sea of web languages, and not the be-all and end-all of the web. JavaFX is the sort of thing that can move us in that direction.

We started working with JavaFX under the assumption that it would be open source, preferably with a license compatible with the GPL 2.0. This makes sense as OpenJDK is GPL 2.0. Certainly, Sun gave the impression explicitly that their intention was to make it open source.

New Default Browser Home Page - Under Construction

New Default Browser Home Page - Under Construction

Now, as widely known, JavaFX 1.0 differs considerably from its preview releases both in its syntax and APIs. Naturally, we’d like to update Lobo’s preview support of JavaFX Script, and we’ve already made some progress in this area. We’re creating a site at fx.lobobrowser.org that will be our new JavaFX-based default home page for the browser. Right now we only have an “under construction” page there and you need Lobo 0.98.4 (not released yet) to see it. It’s a cool “under construction” page, nevertheless, considering that it only uses a simple under-construction icon. The effects you see there (screenshot to your right) are entirely done in not too many lines of JavaFX code. It’s not one big image.

As part of bringing Lobo up to date with JavaFX 1.0, I was reading the license that comes with the SDK. I don’t know if it’s just me but some parts of it seem completely unreasonable and unworkable. Take, for example, the following section.

4. JavaFX Technology Restrictions. You may not create, modify, or change the behavior of classes, interfaces, or subpackages that are in any way identified as “javafx”, “sun” or similar convention as specified by Sun in any naming convention designation.

This means that if you find a problem with the software, you can’t fix it yourself. You can’t create a quick patch that will hold you over until a fix is made official. That’s not even the problem, though. What if you want to create a specialized application that requires JavaFX technology to behave differently?

Personally, I’m not too worried about that one because we’re able to get the JavaFX runtime to work with Lobo without making modifications to JavaFX libraries. Consider the following restriction, however.

5. (a) The copies of Software provided to you under this Agreement are licensed, not sold, to you by Sun. Sun reserves all rights not expressly granted. (b) You may make a single archival copy of Software, but otherwise may not copy, modify, or distribute Software. However if the Sun documentation accompanying Software lists specific portions of Software, such as header files, class libraries, reference source code, and/or redistributable files, that may be handled differently, you may do so only as provided in the Sun documentation. (c) You may not rent, lease, lend or encumber Software. (d) Unless enforcement is prohibited by applicable law, you may not decompile, or reverse engineer Software. (e) The terms and conditions of this Agreement will apply to any Software updates, provided to you at Sun’s discretion, that replace and/or supplement the original Software, unless such update contains a separate license. (f) You may not publish or provide the results of any benchmark or comparison tests run on Software to any third party without the prior written consent of Sun. (g) Software is confidential and copyrighted. (h) Unless otherwise specified, if Software is delivered with embedded or bundled software that enables functionality of Software, you may not use such software on a stand-alone basis or use any portion of such software to interoperate with any program(s) other than Software. (i) Software may contain programs that perform automated collection of system data and/or automated software updating services. System data collected through such programs may be used by Sun, its subcontractors, and its service delivery partners for the purpose of providing you with remote system services and/or improving Sun’s software and systems. (j) Software is not designed, licensed or intended for use in the design, construction, operation or maintenance of any nuclear facility and Sun and its licensors disclaim any express or implied warranty of fitness for such uses. (k) No right, title or interest in or to any trademark, service mark, logo or trade name of Sun or its licensors is granted under this Agreement.

You can’t redistribute any part of the software? Suppose you want to include some JavaFX classes as part of your existing Swing application. You obviously need to redistribute javafxrt.jar and other such JAR files. That, or you have to ask your users to download the JavaFX 1.0 SDK in addition to the JRE, and have them use javafx instead of java to run your application. This seems highly restrictive and inconvenient for everyone.

The license has the following clause, though: “However if the Sun documentation accompanying Software lists specific portions of Software, such as header files, class libraries, reference source code, and/or redistributable files, that may be handled differently, you may do so only as provided in the Sun documentation.” Unfortunately, I don’t see anything about redistribution of JAR files over at JavaFX.com, the site where I’d expect the aforementioned documentation to be located.

I think Sun is a reasonable company, in any case, and these issues will be resolved in time (perhaps with some pressure from the community). In the meantime, we’ll have to make some assumptions about the JAR files that can be distributed. I’d suggest they are the following.

javafxc.jar (compiler is already GPL)
javafx-swing.jar
javafx-rt.jar
javafxgui.jar
websvc.jar
Scenario.jar
jmc.jar

I can see that redistributing DLLs, particularly the on2 video codec DLLs, would be a problem. We’re not planning to redistribute those, and we’ll have to figure something out about video playback.

But in regards to the other JAR files, unless a lawyer from Sun sends us a cease & desist, we’re just going to assume that it is perfectly reasonable and expected that you should be able to redistribute the unmodified JAR files as part of a free/open-source application. Hopefully the licensing issues will get ironed out in time.

Posted in javafx | Tagged: , , | 4 Comments »

 
Follow

Get every new post delivered to your Inbox.