Java SWT web browser embedded in swing on the Raspberry PI

As I was working on a Rapsberry PI project I had a requirment to run a web browser inside a Java Swing project. I worked 3 month to get a browser on the Raspberry PI, I have tried various options including JavaFX webview, DJNativeSwing webBrowser, JCEF(embedded chromium) which all didnt work. finally after some time I found the answer: a native SWT web browser, and it worked with no errors, no exceptions, no missing DLLs.

here is the basic solution steps:
1. install requiered libraries:
sudo apt-get install libswt-gtk-3-jni libswt-gtk-3-java libswt-webkit-gtk-3-jni libwebkitgtk-1.0-0
2. create a simple java swt browser app as folows:

// Import SWT. import org.eclipse.swt.SWT; // Import UI components. import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; // Import the browser component. import org.eclipse.swt.browser.Browser; // Create a class for instantiating the encapsulating Java application. public final class Main { // Holds the Java window and its properties. private Display display; private Shell shell; private FillLayout layout; // Holds the browser widget. private Browser browser; // Application title and settings. private static final String title = "Sample JJR Application"; private static final int height = 800; private static final int width = 600; // RIA location. private static final String URL = "http://localhost/"; // Class constructor used for creating the basic Java UI, including the browser. public Main() { // Prepare window. this.display = new Display(); this.shell = new Shell(this.display); this.shell.setSize(Main.width, Main.height); this.shell.setText(Main.title); this.layout = new FillLayout(); this.shell.setLayout(this.layout); // Create browser. this.browser = new Browser(this.shell,SWT.NONE); this.browser.setUrl(Main.URL); // Add custom JavaScript function. new HelloWorld( this.browser, // Browser widget. "Hello" // JS function name. ); // Display window. this.shell.open(); while (!this.shell.isDisposed()) { if (!this.display.readAndDispatch()) this.display.sleep(); } this.display.dispose(); } // Application entry point. public static void main(String[] args) { // Start the application. new Main(); } }

3. include the /usr/share/java/swt-gtk-3.8.jar in the class path or just import the jar in to your project, and export the project to a runnable jar.

to embed the browser on swing use the code above ( taken from https://gist.github.com/r10r/2305091 )

import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** * A simple canvas that encapsulates a SWT Browser instance. * Add it to a AWT or Swing container and call "connect()" after * the container has been made visible. */ public class BrowserCanvas extends Canvas { private Thread swtThread; private Browser swtBrowser; /** * Connect this canvas to a SWT shell with a Browser component * and starts a background thread to handle SWT events. This method * waits until the browser component is ready. */ public void connect() { if (this.swtThread == null) { final Canvas canvas = this; this.swtThread = new Thread() { @Override public void run() { try { Display display = new Display(); Shell shell = SWT_AWT.new_Shell(display, canvas); shell.setLayout(new FillLayout()); synchronized (this) { swtBrowser = new Browser(shell, SWT.NONE); this.notifyAll(); } shell.open(); while (!isInterrupted() && !shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } shell.dispose(); display.dispose(); } catch (Exception e) { interrupt(); } } }; this.swtThread.start(); } // Wait for the Browser instance to become ready synchronized (this.swtThread) { while (this.swtBrowser == null) { try { this.swtThread.wait(100); } catch (InterruptedException e) { this.swtBrowser = null; this.swtThread = null; break; } } } } /** * Returns the Browser instance. Will return "null" * before "connect()" or after "disconnect()" has * been called. */ public Browser getBrowser() { return this.swtBrowser; } /** * Stops the swt background thread. */ public void disconnect() { if (swtThread != null) { swtBrowser = null; swtThread.interrupt(); swtThread = null; } } /** * Ensures that the SWT background thread * is stopped if this canvas is removed from * it's parent component (e.g. because the * frame has been disposed). */ @Override public void removeNotify() { super.removeNotify(); disconnect(); } /** * Opens a new JFrame with BrowserCanvas in it */ public static void main(String[] args) { // Required for Linux systems System.setProperty("sun.awt.xembedserver", "true"); // Create container canvas. Note that the browser // widget will not be created, yet. final BrowserCanvas browserCanvas = new BrowserCanvas(); browserCanvas.setPreferredSize(new Dimension(800, 600)); JPanel panel = new JPanel(new BorderLayout()); panel.add(browserCanvas, BorderLayout.CENTER); // Add container to Frame JFrame frame = new JFrame("My SWT Browser"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setContentPane(panel); frame.pack(); // This is VERY important: Make the frame visible BEFORE // connecting the SWT Shell and starting the event loop! frame.setVisible(true); browserCanvas.connect(); // Now we can open a webpage, but remember that we have // to use the SWT thread for this. browserCanvas.getBrowser().getDisplay().asyncExec(new Runnable() { @Override public void run() { browserCanvas.getBrowser().setUrl("http://www.google.com"); Shell shell = browserCanvas.getBrowser().getShell(); shell.pack(); } }); } }

in this solution we use swing Jframe and a JPanel with a border layout. this layout works, but card layout does not work with this browser. you have to create the browser canvas and add it to the frame and set the frame visible before connecting to the swt browser, or else it will not work.

this solution works on the raspberry, but there are some problems. if you want to close the browser, and then display it again you simply call disconnect and connect, it will work on windows. on the raspberry when you try to call connect after disconnect it will crash the JVM. so you need to modify the code to keep the SWT Browser,Shell,Display not disposing, and do not disconnect the canvas from the JFrame. if you disconnect the canvas from the JFrame you cannot re connect the canvas. you need to dispose the SWT elements after the JFrame windowClosed event has fired on a WindowListener. its not a pretty solution but its the only solution I have found.

please feel free to comment about this, and ask questions.



תגובות

5VNxzJ


Could I order a new chequebook, please? http://blog.cilek.com/etiket/tasarim/ co to jest apcalis Richards concluded by saying that removing the remaining barriers to switching is essential in ensuring that the communications sector "continues to deliver real improvement in value for money during a time when the cost of living is so important for millions of people across the UK and Europe".

5VNxzJ

Could I order a new chequebook, please? http://blog.cilek.com/etiket/tasarim/ co to jest apcalis Richards concluded by saying that removing the remaining barriers to switching is essential in ensuring that the communications sector "continues to deliver real improvement in value for money during a time when the cost of living is so important for millions of people across the UK and Europe".

K0Zlq


How many more years do you have to go? http://blog.cilek.com/etiket/trio/ side effects of using penegra SINGAPORE, Sept 18 (Reuters) - Huawei Technologies Co Ltd expects to take in more than $2 billion in revenuesselling 4G gear this year as global carriers from China toEurope expand their networks, senior company executives said onWednesday.

K0Zlq

How many more years do you have to go? http://blog.cilek.com/etiket/trio/ side effects of using penegra SINGAPORE, Sept 18 (Reuters) - Huawei Technologies Co Ltd expects to take in more than $2 billion in revenuesselling 4G gear this year as global carriers from China toEurope expand their networks, senior company executives said onWednesday.

k5YGB


Best Site good looking http://rumahminimalisku.web.id/2018/02/24/plafon-ruang-tamu/ zyban cst uk And while area bars and restaurants are typically packed on game days, the neighborhood is a ghost town when neither team is playing. After the games, most fans go straight back to their homes in the suburbs.

k5YGB

Best Site good looking http://rumahminimalisku.web.id/2018/02/24/plafon-ruang-tamu/ zyban cst uk And while area bars and restaurants are typically packed on game days, the neighborhood is a ghost town when neither team is playing. After the games, most fans go straight back to their homes in the suburbs.

KRoRR


Have you got a current driving licence? http://karc.us/71305/stancenation-skyline.html assurans synonym It has to be said, though, that both macroprudential policy and the way it would be organised within the euro zone are in their infancy. When it was used by Spain during its housing bubble, it wasn’t very effective. Some observers think the whole policy is overrated; others that it just wasn’t pursued vigorously enough. The best guess is that macroprudential policy would help if it was actively implemented but that it would be wrong to expect it to do the whole job of stopping an economy from overheating. This is why euro zone countries should adopt another approach as well: “counter-cyclical” fiscal policies.

KRoRR

Have you got a current driving licence? http://karc.us/71305/stancenation-skyline.html assurans synonym It has to be said, though, that both macroprudential policy and the way it would be organised within the euro zone are in their infancy. When it was used by Spain during its housing bubble, it wasn’t very effective. Some observers think the whole policy is overrated; others that it just wasn’t pursued vigorously enough. The best guess is that macroprudential policy would help if it was actively implemented but that it would be wrong to expect it to do the whole job of stopping an economy from overheating. This is why euro zone countries should adopt another approach as well: “counter-cyclical” fiscal policies.

MdnCIf


Looking for a job http://conankun.net/page/31/ renitec enalapril maleate 5mg Sea turtle watches: The Florida Fish and Wildlife Commission maintains a list of organizations that are permitted to conduct public sea turtle watches at myfwc.com/education/wildlife/sea-turtle/where-to-view.

MdnCIf

Looking for a job http://conankun.net/page/31/ renitec enalapril maleate 5mg Sea turtle watches: The Florida Fish and Wildlife Commission maintains a list of organizations that are permitted to conduct public sea turtle watches at myfwc.com/education/wildlife/sea-turtle/where-to-view.

הוסף תגובה

שם משתמש: 

אימייל: 

 

הודעה: