Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何嵌入角度2+;是否仅将应用程序作为GUI导入JavaFX WebView?_Java_Angular_Javafx_Webview_Angular Cli - Fatal编程技术网

如何嵌入角度2+;是否仅将应用程序作为GUI导入JavaFX WebView?

如何嵌入角度2+;是否仅将应用程序作为GUI导入JavaFX WebView?,java,angular,javafx,webview,angular-cli,Java,Angular,Javafx,Webview,Angular Cli,我正在开发一个简单的Java客户机应用程序,我希望在GUI中使用HTML和web应用程序框架,而不是使用Swing或JavaFX 因此,我正在使用Angular 6(使用Angular cli生成)设计、构建和测试我的整个应用程序,我想使用JavaFX WebView和WebEngine组件来指向我的Angular UI 有没有什么简单的/现成的/最佳实践的方法来连接所有东西 我希望用户只是启动应用程序,甚至没有意识到他正在浏览webby。如果可能的话,我甚至不会启动任何web服务器。我只需要一

我正在开发一个简单的Java客户机应用程序,我希望在GUI中使用HTML和web应用程序框架,而不是使用Swing或JavaFX

因此,我正在使用Angular 6(使用Angular cli生成)设计、构建和测试我的整个应用程序,我想使用JavaFX WebView和WebEngine组件来指向我的Angular UI

有没有什么简单的/现成的/最佳实践的方法来连接所有东西

我希望用户只是启动应用程序,甚至没有意识到他正在浏览webby。如果可能的话,我甚至不会启动任何web服务器。我只需要一个自包含的应用程序,并使用angular框架仅用于GUI目的

如果我必须启动一个web服务器,我希望在幕后这样做,而不希望用户意识到这一点

问题

  • 我试图让WebEngine指向内置的angular应用程序,但angular cli是现成的
  • 我试图使用com.sun.net.httpserver,但web上的所有解释都只说明如何实现自己的虚拟HttpHandler,因此我无法理解如何将服务器绑定到实际构建的web应用程序(位于项目路径中的文件夹中)或如何将web应用程序部署到httpserver中,以正确的为准

您可以使用webkit嵌入任何HTML应用程序——jvm的webkit版本是相对最新的,在我上次检查时,可能缺少一些函数,WebGL可能是

要使其正常工作,请不要使用
文件://
协议,创建自己的Web服务器是过分的。您只需要定义自己的protocl并在java层中声明它

例如:

以下是我的自定义协议实现:

/**
 * Register a protocol handler for URLs like this: <code>myapp:///pics/sland.gif</code><br>
 */
public class MyURLConnection extends URLConnection
{

    protected MyURLConnection(URL url) {
        super(url);
    }

    private byte[] data;

    @Override
    public void connect() throws IOException
    {
        if (connected)
        {
            return;
        }
        loadImage();
        connected = true;
    }

    public String getHeaderField(String name)
    {
        if ("Content-Type".equalsIgnoreCase(name))
        {
            return getContentType();
        }
        else if ("Content-Length".equalsIgnoreCase(name))
        {
            return "" + getContentLength();
        }
        return null;
    }

    public String getContentType()
    {
        String fileName = getURL().getFile();
        String ext = fileName.substring(fileName.lastIndexOf('.')+1);
        switch(ext){
        case "html":return "text/html";
        case "jpg":
        case "png":return "image/"+ext;
        case "js": return "application/javascript";
        }
        return "text/"+ext;
         // TODO: switch based on file-type "image/" + ext
    }

    public int getContentLength()
    {
        return data.length;
    }

    public long getContentLengthLong()
    {
        return data.length;
    }

    public boolean getDoInput()
    {
        return true;
    }

    public InputStream getInputStream() throws IOException
    {
        connect();
        return new ByteArrayInputStream(data);
    }

    /**
     * Reads all bytes from an input stream and writes them to an output stream.
     */
    private static long copy(InputStream source, OutputStream sink)
        throws IOException
    {
        long nread = 0L;
        byte[] buf = new byte[8192];
        int n;
        while ((n = source.read(buf)) > 0) {
            sink.write(buf, 0, n);
            nread += n;
        }
        return nread;
    }

    private void loadImage() throws IOException
    {
        if (data != null)
        {
            return;
        }

            String fileName = getURL().getFile();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            copy(this.getClass().getResourceAsStream(fileName),byteArrayOutputStream);
           data = byteArrayOutputStream.toByteArray();

    }

    public OutputStream getOutputStream() throws IOException
    {
        // this might be unnecessary - the whole method can probably be omitted for our purposes
        return new ByteArrayOutputStream();
    }

    public java.security.Permission getPermission() throws IOException
    {
        return null; // we need no permissions to access this URL
    }

}

public class MyURLHandler extends URLStreamHandler
{

    @Override
    protected URLConnection openConnection(URL url) throws IOException
    {
        return new MyURLConnection(url);
    }

}

public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory
{

    public URLStreamHandler createURLStreamHandler(String protocol)
    {
        if (protocol.equals("myapp"))
        {
            return new MyURLHandler();
        }
        return null;
    }

}
然后只需在javafx启动中注册协议:

public void start(Stage stage) {
    URL.setURLStreamHandlerFactory(new MyURLStreamHandlerFactory());
    // etc. 
并使用url
myapp://anyhost/yourfile.html
在您的webkit中(不使用任何主机,请使用您想要的任何东西或修改协议)

编辑: 我在github上的项目(正在进行中)中完成了这项工作:您只需启动
WebDesktop
main类。它使用src/main/resources的资源

最终,我通过使用嵌入式Jetty服务于我的角度应用程序,成功地解决了这个问题

@Slf4j
public class MyEmbeddedAngularApp extends Application {

    private static final String APPLICATION_TITLE = "My Embedded Angular Application";

    /**
     * The service executing the server.
     */
    private ExecutorService executor = Executors.newSingleThreadExecutor();

    @Override
    public void start(Stage stage) throws Exception {
        startServer();

        //Create the root AnchorPane
        AnchorPane root = new AnchorPane();

        //Initialize the Web UI
        WebView browser = new WebView();
        WebEngine webEngine = browser.getEngine();
        webEngine.load("http://localhost:2342");

        //add WebView to root
        root.getChildren().add(browser);

        //Setting up the scene
        Scene scene = new Scene(root);
        stage.setTitle(APPLICATION_TITLE);
        stage.setScene(scene);

        //Let the show begin!
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void startServer() throws Exception {
        Server server = new Server(2342);

        WebAppContext webapp = new WebAppContext();
        webapp.setContextPath("/");
        File warFile = new File("./src/main/resources/my-app/dist/my-app");
        webapp.setWar(warFile.getAbsolutePath());

        server.setHandler(webapp);
        server.setStopAtShutdown(true);

        server.start();

        server.dumpStdErr();

        executor.submit(() -> {
            try {
                server.join();
            } catch (InterruptedException e) {
                log.error("Could not start the server");
            }
        });
    }

}

我不明白为什么会有反对票,也许我遗漏了什么?我能够用一个虚拟的myfile.html使这个解决方案工作。但它不能与Angular应用程序一起工作,也就是说,当我让WebEngine加载由Angular-cli创建的src文件夹或dist/my-app文件夹的index.html时,它不能工作。你真的使用了文件以外的协议吗?它与javascript、内容类型和同源策略有关:您必须使用application/javascript内容类型为js提供服务,并使用同源策略。我的github示例使用javascript项目,angular项目的编译JS版本也应该以同样的方式工作。@DanieleRepici您是否尝试过不使用文件协议?是的,我尝试过,但不幸的是它没有工作。可能有关联?编辑:我不认为是这样,因为它仍然提到了文件协议。。。你有没有用编译过的angular应用程序尝试过你的解决方案?对不起,我现在让它工作了,不知道发生了什么。谢谢你的支持。