我正在开发一个简单的Java客户端应用程序,并且我想为其GUI使用HTML和Web应用程序框架,而不是使用Swing或JavaFX。
因此,我正在使用Angular 6(通过angular-cli生成)设计,构建和测试我的整个应用程序,我想使用JavaFX WebView和WebEngine组件指向我的Angular UI。
是否有任何简便/开箱即用/最佳实践的方式来连接所有内容?
我希望用户只是启动应用程序,甚至不意识到他正在浏览Webby。如果可能的话,我什至不会启动任何Web服务器。我只想要一个独立的应用程序,并且仅将角度框架用于GUI。
如果我必须启动Web服务器,我想在幕后这样做,并且不希望用户意识到。
问题
答案 0 :(得分:2)
您可以使用Webkit嵌入任何HTML应用程序-jvm的Webkit版本是相对最新的,在我上次检查时,可能缺少一些功能,也许是WebGL。
要使其正常运行,请不要使用url: "{{ url('search/search') }}"
协议,而创建自己的Web服务器实在是太过分了。您只需要定义自己的协议并在Java层中声明它即可。
示例在这里:Registering and using a custom java.net.URL protocol
这是我的自定义协议实现:
file://
然后只需在javafx启动中注册协议:
/**
* 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;
}
}
并在您的Webkit中使用URL public void start(Stage stage) {
URL.setURLStreamHandlerFactory(new MyURLStreamHandlerFactory());
// etc.
(不使用任何主机,使用任何您想要的内容或修改协议)
编辑:
我是在github上的项目中进行的(正在进行中):您只需要启动myapp://anyhost/yourfile.html
主类。它使用src / main / resources的资源
https://github.com/pdemanget/blue-browser
答案 1 :(得分:0)
最终,我设法使用嵌入式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");
}
});
}
}