webbrowser.java

来自「jdic,显著提高swing性能的插件」· Java 代码 · 共 832 行 · 第 1/2 页

JAVA
832
字号
/* * Copyright (C) 2004 Sun Microsystems, Inc. All rights reserved. Use is * subject to license terms. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Lesser GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */package org.jdesktop.jdic.browser;import java.util.Vector;import java.net.URL;import java.net.MalformedURLException;import java.awt.*;import java.awt.event.*;import java.security.*;import org.jdesktop.jdic.init.JdicInitException;import org.jdesktop.jdic.init.JdicManager;import org.jdesktop.jdic.browser.internal.WebBrowserUtil;/** * A <code>WebBrowser</code> component represents a blank rectangular area of  * the screen onto which the application can display webpages or from which the * application can trap events from the browser window. In order to show <code> * WebBrowser</code> component in GUI, users need to add <code>WebBrowser</code>  * to a top-level container, such as <code>Frame</code>. * <p> * The class that is interested in processing a <code>WebBrowser</code> event  * should implement interface <code>WebBrowserListener</code>, and the object  * created with that class should use WebBrowser's <code>addWebBrowserListener * </code> method to register as a listener. * <p> * As an AWT component, a <code>WebBrowser</code> component must be hosted by  * a native container somewhere higher up in the component tree (for example,  * by a JPanel object). *  * @see WebBrowserEvent * @see WebBrowserListener * * @author Kyle Yuan * @version 0.1, 03/07/17 */public class WebBrowser extends Canvas{    private MyFocusListener focusListener = new MyFocusListener();    // eventThread should be initialized after JdicManager.initShareNative()     // in static block.    private static NativeEventThread eventThread;     private Vector webBrowserListeners = new Vector();    private int instanceNum;    private static int lastInstanceNum = 0;        // WebBrowser status.    private boolean isInitialized = false;    private boolean isBackEnabled = false;    private boolean isForwardEnabled = false;    private String initFailureMessage = "WebBrowser is not initialized.";    /**     * boolean flag used to indicate how to dispose this instance.     * @see #dispose()     * @see #removeNotify()     */    final private boolean autoDispose;    /**     * Used to cache the url before dispose this instance.     *     * @see #dispose()     * @see #addNotify()     * @see #removeNotify()     */    private URL urlBeforeDispose = null;    static {        // Add the initialization code from package org.jdesktop.jdic.init.        // To set the environment variables or initialize the set up for         // native libraries and executable files.        try {            JdicManager jm = JdicManager.getManager();            jm.initShareNative();            jm.initBrowserNative();        } catch (JdicInitException e){            e.printStackTrace();        }        eventThread = new NativeEventThread();                AccessController.doPrivileged(                new PrivilegedAction() {                    public Object run() {                        System.loadLibrary("jdic");                        return null; // nothing to return                    }                }            );    }    void setInitialized(boolean b) {        isInitialized = b;    }    void setInitFailureMessage(String msg) {        initFailureMessage = msg;    }        /**     * Constructs a new <code>WebBrowser</code> object with no URL specified.     * This instance will automatically dispose itself when <code>removeNotify()     * </code> is called.     * <p>     * This constructor is equivalent to <code>WebBrowser(true)</code>.     *     * @see #WebBrowser(boolean)     * @see #removeNotify()     * @see #dispose()     */    public WebBrowser() {        this(true);    }    /**     * Constructs a new <code>WebBrowser</code> object with the specified     * boolean value <code>autoDispose</code> as the flag which indicates     * whether this instance will automatically dispose itself in <code>     * removeNotify()</code> or should be disposed by the developer directly     * calling <code>dispose()</code>.     * <p>     * This constructor is equivalent to <code>WebBrowser(null, autoDispose)     * </code>.     *     * @param autoDispose ture to indicate this instance will automatically     *        dispose itself in <code>removeNotify()</code>; false to indicate     *        the developer should call <code>dispose()</code> when this     *        instance is no longer needed.     *     * @see #removeNotify()     * @see #dispose()     * @see #isAutoDispose()     */    public WebBrowser(boolean autoDispose){        this(null, autoDispose);    }    /**     * Constructs a new <code>WebBrowser</code> with an URL specified. This     * instance will automatically dispose itself when <code>removeNotify()     * </code> is called.     * <p>This constructor is equivalent to <code>WebBrowser(url, true)</code>.     * @param url the URL to be shown in this instance.     *     * @see #WebBrowser(boolean)     * @see #removeNotify()     * @see #dispose()     */    public WebBrowser(URL url) {        this(url, true);    }    /**     * Constructs a new <code>WebBrowser</code> with an specified URL and     * boolean flag to indicate the dispose schema.     *     * @param url the URL to be shown in this instance.     * @param autoDispose ture to indicate this instance will automatically     *        dispose itself in <code>removeNotify()</code>; false to indicate     *        the developer should call <code>dispose()</code> when this     *        instance is no longer needed.     *     * @see #removeNotify()     * @see #dispose()     * @see #isAutoDispose()     */    public WebBrowser(URL url, boolean autoDispose){        this.autoDispose = autoDispose;        synchronized(WebBrowser.class) {            instanceNum = lastInstanceNum;            lastInstanceNum++;        }        eventThread.attachWebBrowser(this);        if (0 == instanceNum) {                       eventThread.start();            eventThread.fireNativeEvent(instanceNum, NativeEventData.EVENT_INIT);        }        if (null != url) {            setURL(url);        }        setFocusable(true);        addFocusListener(focusListener);    }    /**     * Creates the peer for this WebBrowser component. The peer allows us to     * modify the appearance of the WebBrowser component without changing its     * functionality.     *     * @see #removeNotify()     */    public void addNotify() {        super.addNotify();        if(!isInitialized) {            eventThread.fireNativeEvent(instanceNum,                     NativeEventData.EVENT_CREATEWINDOW);            /**             * Reset the URL before this instance was disposed.             * urlBeforeDispose is set in {@link #disposed()}.             */            if(urlBeforeDispose != null){                this.setURL(urlBeforeDispose);                urlBeforeDispose = null;            }        }        if(!autoDispose){            this.setVisible(true);        }    }    /**     * Makes this WebBrowser component undisplayable by destroying it native     * screen resource if the <code>isAutoDispose()</code> returns true. Or just     * make this instance invisible if the <code>isAutoDispose()</code> return     * false. <p>     * This method is called by the toolkit internally and should not be called     * directly by programs.     * <p>     * If <code>isAutoDispose()</code> return false, developer should call     * <code>dispose()</code> when this instance is no longer needed.     * Otherwise, it resource will never be released untill this JVM exit.     *     * @see #addNotify()     * @see #dispose()     * @see #isAutoDispose()     */    public void removeNotify() {        if(autoDispose){            dispose();        }else{            this.setVisible(false);        }    }    /**     * Release this instance's resource and make it undisplayable. If <code>     * isAutoDispose()</code> return true, this method will be called by the     * toolkit internally. If <code>isAutoDispose()</code> return false, this     * method should be called by developer when this instance is no longer     * needed.     *     * @see #removeNotify()     * @see #isAutoDispose()     */    public void dispose() {        urlBeforeDispose = this.getURL();        Thread disposeThread = new Thread() {            public void run() {                synchronized( WebBrowser.this ){                    eventThread.fireNativeEvent(instanceNum,                             NativeEventData.EVENT_DESTROYWINDOW);                    try {                        // wait untill we get the message                         //   WebBrowserEvent.WEBBROWSER_DESTROYWINDOW_SUCC                        // from native process.                        WebBrowser.this.wait();                    } catch (InterruptedException e) {                    }                }                WebBrowser.super.removeNotify();                setInitialized(false);            }        };        disposeThread.start();    }    /**     * Return the boolean flag which indicates how to dispose this instance.     *     * @return true if this instance should be disposed by itself when     *         <code>removeNotify()</code> is called. false if this instance     *         should be disposed by the developer directly calling     *         <code>dispose()</code> when it is no longer needed.     *     * @see #removeNotify()     * @see #addNotify()     * @see #dispose()     */    public boolean isAutoDispose(){        return autoDispose;    }    /**     * Moves and resizes this component. The new location of the top-left      * corner is specified by <code>x</code> and <code>y</code>, and the new      * size is specified by <code>width</code> and <code>height</code>.     *     * @param x - the new x-coordinate of this component     * @param y - the new y-coordinate of this component     * @param width - the new width of this component     * @param height - the new height of this component     */    public void setBounds(int x, int y, int width, int height) {            super.setBounds(x, y, width, height);        eventThread.fireNativeEvent(instanceNum,                 NativeEventData.EVENT_SET_BOUNDS,                 new Rectangle(x, y, width, height));    }    /*     * Dispatches a WebBrowserEvent to the Java embeddor, called by      * NativeEventThread.processIncomingMessage.      */    void dispatchWebBrowserEvent(WebBrowserEvent e) {        int eid = e.getID();        WebBrowserUtil.trace("Got event from NativeEventThread " + eid);        // native browser needs immediate return value for these two events.               // Special trigger messages beginning with a '@' character, to give         // the native browser a yes or no to continue an operation(navigating        // an URL or openning a new window).        String msg = "@" + instanceNum + "," + eid + ",";        if (WebBrowserEvent.WEBBROWSER_BEFORE_NAVIGATE == eid) {            URL url = null;            try {                url = new URL(e.getData());            } catch (MalformedURLException ex1) {                try {                	// IE omits the file:/ protocol for local files, append it.                                        if (!WebBrowserUtil.isDefaultBrowserMozilla()) {                        url = new URL("file:/" + e.getData());                    }                } catch (MalformedURLException ex2) {                                    }            }                        msg += willOpenURL(url) ? "0" : "1";            eventThread.messenger.sendMessage(msg);            return;        }        else if (WebBrowserEvent.WEBBROWSER_BEFORE_NEWWINDOW == eid) {            msg += willOpenWindow() ? "0" : "1";            eventThread.messenger.sendMessage(msg);            return;        }        else if (WebBrowserEvent.WEBBROWSER_COMMAND_STATE_CHANGE == eid) {            String data = e.getData();            if (data.startsWith("forward")) {                isForwardEnabled = data.substring(8).equals("1");                WebBrowserUtil.trace("Forward State changed = "                         + isForwardEnabled);            }            else if (data.startsWith("back")) {                isBackEnabled = data.substring(5).equals("1");                WebBrowserUtil.trace("Back State changed = " + isBackEnabled);            }            return;        }        else if (WebBrowserEvent.WEBBROWSER_FOCUS_REQUEST == eid) {            WebBrowserUtil.trace("Got event from brower: Focus request.");            requestFocus();            return;        }        else if (WebBrowserEvent.WEBBROWSER_DESTROYWINDOW_SUCC == eid){            WebBrowserUtil.trace("Got event from brower: Destory window " +                    "succeeds.");            synchronized(this){                // notify the disposeThread in removeNotify().                this.notify();            }       }        // for the normal case, call the corresponding method in listeners.        int size;        Vector tl;        synchronized (this) {            size = webBrowserListeners.size();            if (size == 0) {                return;            }            tl = (Vector) webBrowserListeners.clone();        }        for (int i = 0; i < size; ++i) {            WebBrowserListener listener = (WebBrowserListener) tl.elementAt(i);            switch (eid) {                case WebBrowserEvent.WEBBROWSER_DOWNLOAD_STARTED:                    listener.downloadStarted(e);                    break;                case WebBrowserEvent.WEBBROWSER_DOWNLOAD_COMPLETED:                    listener.downloadCompleted(e);                    break;                case WebBrowserEvent.WEBBROWSER_DOWNLOAD_PROGRESS:                    listener.downloadProgress(e);                    break;                case WebBrowserEvent.WEBBROWSER_DOWNLOAD_ERROR:                    listener.downloadError(e);                    break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?