Application Execution Modes

3 Application Execution(执行) Modes(模式)

One of the main features of the JavaFX application model is that you can write one application and easily deploy it several different ways. The user can experience the same application running on the desktop, in a browser, or starting from a link in a web page.

However, different execution modes are not completely equivalent(相等). There are some important differences to keep in mind(牢记) while developing the application.

This page contains the following topics:

3.1 Execution Modes

One of the main features of the JavaFX application model is that the applications you develop can be deployed in several different ways, as described in Table 3-1.

Table 3-1 JavaFX Execution Modes

Execution ModeDescription

Run as a standalone(独立) program

The application package is available on a local drive. Users launch it using a Java launcher(启动程序), such as java -jar MyApp.jar, or by double-clicking the application JAR file.

Launched from a remote server using Web Start

Users click a link in a web page to start the application from a remote web server. Once downloaded, a Web Start application can also be started from a desktop shortcut(捷径).

Embedded(嵌入式) into a web page

JavaFX content(内容) is embedded in the web page and hosted on a remote web server.

Launched as a self-contained(独用的) application(跟其他的window程序的安装模式是一样的,比如QQ,这样看起来更加符合很多人的习惯)

Application is installed(安装) on the local drive and runs as a standalone program using a private copy of Java and JavaFX runtimes. The application can be launched in the same way as other native applications for that operating system, for example using a desktop shortcut or menu entry(入门).


Each execution(执行) environment has its own specific complications(并发症) and usability(可用性) issues. For example, for remote applications the loading phase can be very long because the application has to be loaded from the network. This is less of an issue for applications that run on a local drive.

3.2 Understanding Feature Differences

Figure 3-1 lists some of the features that behave(表现) differently in different environments. The following sections(部分) describe the figure(说明) in more detail.

Figure 3-1 Features of Deployment Types

3.2.1 Preloader(预载) Support

The preloader is a small JavaFX application that receives notifications(通知) about application loading and initialization(初始化) progress. The preloader is used with all execution modes, but depending on the execution mode, the preloader implementation receives a different set of events and optimal(最佳) behavior(行为) may be different.

For example, in self-contained application or standalone execution mode or when launched from a shortcut, the preloader will not get any loading progress events, because there is nothing to load. See Chapter 9, "Preloaders" for information about preloader implementation and differences in behavior.

3.2.2 Desktop Integration(集成) via Shortcut

Most of the operating systems allow applications to simplify subsequent(连串) launch and integrate with the user's desktop by creating a desktop shortcut or adding a link to the programs menu or dock(工具).

Built-in support for desktop shortcuts is available for self-contained and web-deployed applications. There is no built-in support for standalone applications.

如下图所示的standalone applications是不内置支持桌面快捷键,当然在window下是可以自己创建所谓的桌面快捷键方式的


3.2.3 Built-In Proxy Support

Properly packaged JavaFX application have proxy settings initialized according to Java Runtime configuration settings. By default, this means proxy settings will be taken from the current browser if the application is embedded into a web page, or system proxy settings will be used. Proxy settings(代理服务器设置) are initialized by default in all execution modes.

3.2.4 Run in Sandbox(砂箱) Unless Signed and Trusted

WebStart and embedded applications are, by default, run in a restricted(限制) environment, known as a sandbox. In this sandbox, Java Runtime does the following:

  • Protects users against malicious(恶毒) code that could affect local files.

  • Protects enterprises(企业) against code that could attempt to access or destroy data on networks.

Applications fall into three categories(类别): signed and trusted, signed and not trusted, and unsigned. When running on a client (unless launched as a standalone application), un-trusted applications operate with maximum restrictions within a security sandbox that allows only a set of safe operations.

Un-trusted applications cannot perform the following operations:

  • They cannot access client resources such as the local filesystem, executable(可执行文件) files, system clipboard(剪贴板), and printers.

  • They cannot connect to or retrieve resources from any third-party server (in other words, any server other than the server it originated(起源) from).

  • They cannot load native libraries.

  • They cannot change the SecurityManager.

  • They cannot create a ClassLoader.

  • They cannot read certain system properties. See System Properties for a list of forbidden(被禁止) system properties.

3.2.5 Auto-Updates

JavaFX applications that run from a web page or were earlier installed from the web automatically check for availability of updates to the application at the original location where the application is loaded. This happens every time an application starts, and, by default, the update runs in the background. The application is automatically updated if updates are detected.

For standalone and self-contained applications, you are responsible(负责) for handling updates.

3.2.6 Deployment Toolkit

The Deployment Toolkit performs two important functions:

  • It helps to simplify web deployment of JavaFX applications by managing updates.

  • It improves the end user experience while waiting for applications to start.

These two functions are intertwined(交织), because the application startup phase(阶段) is a critical(批评) component(元件) of user satisfaction. For example, the Deployment Toolkit verifies(验证) that the user has JavaFX Runtime installed, and if not, it will offer to install it before trying to run the application, without much effort on the user's part.

The Deployment Toolkit provides a JavaScript API and is only available for applications embedded in a web page or launched from a web page.

For more information about the Deployment Toolkit, see Chapter 7, "Deployment in the Browser."

3.2.7 Communicate to the Host Web Page

Applications embedded into a web page can communicate with it using JavaScript. To initiate(开始) communication,the application must get the web context from the JavaFX HostServices API.For any other execution environment, an attempt to get a reference to web context returns null.

See Chapter 8, "JavaFX and JavaScript" for information about using JavaScript to communicate with the browser.

3.2.8 Managing Platform Dependencies

To run JavaFX content, recent versions of the Java and JavaFX runtimes are required. Unless the application is self-contained, the Java and JavaFX runtimes need to be installed on the user's system.

For most users, JavaFX 2.2 and later will be installed as part of the Java Runtime and will be auto-updated to the latest secure(稳定的) version. If the user does not have the required version of the Java or JavaFX runtime he or she will be guided to install it.

However, there are situations in which system installations of the Java and JavaFX runtime and the auto-update functionality are not sufficient(满足). For example:

  • The user does not have admin permissions to install the runtimes.

  • The user requires an older version of Java for other applications.

  • Users who need multiple system installations feel they are too complicated(复杂).

  • You want to set the exact(确切) version of Java and JavaFX to be used by your application.

  • Your distribution(发布) channel(渠道) disallows(不允许) dependencies on external(外部) frameworks

These issues are resolved if you choose to deploy your application as a self-contained application. The Java and JavaFX runtimes will be included in your application package, and users do not need to install them separately. The self-contained application package can be as simple as a .zip file distribution, or it can be wrapped into an installable package using technology that is native to the target operating system. See the topic Chapter 5, "Packaging Basics" for more details about self-contained application packages.

3.3 Coding Tips

The following small programming tips work well in all environments and simplify the development and deployment of applications.

3.3.1 Detecting(检测) Embedded Applications

When an application is run in embedded mode, it gets staged with predefined dimensions(尺寸) and cannot update them directly. Example 3-1 shows a very simple code snippet to detect if the application is embedded in the browser. The code can be used in either the main application or the preloader start method.

Example 3-1 Detect if the Application is Embedded in the Browser

public void start(Stage stage) {
    boolean isEmbedded = (stage.getWidth() > 0);
    ...
}

As an alternative, you can try to get a reference to the web context from the Application.getHostServices() method. It will be null unless the applications is embedded.

3.3.2 Accessing Application Parameters

JavaFX applications support both named and unnamed parameters that can be passed in a variety of ways:

  • They can be specified on the command line for a standalone launch.

  • They can be hardcoded in the application package (jar and deployment descriptor).

  • They can be passed from the HTML page in which the application is embedded.

To access parameters from a preloader or main application, use the getParameters() method. For example, the code in Example 3-2 gets a list of all named parameters and their values:

Example 3-2 Get a List of Named Deployment Parameters and Values

Map m = getParameters().getNamed();
int cnt = 0;
String labelText = "List of application parameters: \n";
for(String st: (Set<String>) m.keySet()) {
    labelText += "  ["+st+"] : ["+m.get(st)+"]\n";
    cnt++;
}


3.3.3 Consider the Use of Host Services

The Application.getHostServices() method provides access to execution-mode-specific services, including:

  • Access to information about the code base and the document base.

    For example, for embedded applications this is the URL of the application and URL of the host web page, respectively.

  • Access to the host web page using the JavaScript engine, only available to embedded applications.

  • Ability to open a web page in the browser.

Example 3-3 shows a few things you can do with getHostServices().

Example 3-3 Using getHostServices()

final HostServices services = getHostServices();
        
Button jsButton = new Button("Test Javascript");
jsButton.setOnAction(new EventHandler<ActionEvent>()  {
    public void handle(ActionEvent t) {
        JSObject js = services.getWebContext();
        js.eval("window.alert('Hello from JavaFX')");
    }            
});
 
Button openButton = new Button("Test openDocument()");
    openButton.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
        services.showDocument("http://javafx.com/");
    }
});


3.3.4 Loading Resources

Using the File API and explicit(明确的) relative references to external data files or resources may not work when the application is loaded from the web.

The best way to refer to resources relative to your application is to use the getResource()method on one of the application classes, as shown in Example 3-4.

Example 3-4 Use the getResource() Method to Load Resources

scene.getStylesheets().
    add(this.getClass().getResource("my.css").toExternalForm());

As an alternative, consider using getCodeBase() or getDocumentBase() from the HostServicesclass to refer to resources relative to the application or the location where the application is used.

3.3.5 Resize-Friendly Applications

When an application is embedded into a web page, it cannot control stage dimensions. Dimensions you specify at packaging time are preferences only and can be overridden by the user, for example if the user has custom browser zoom(放大) settings. Moreover(而且), the stage can be resized at runtime any time by the user.

To provide a good user experience, it is necessary to be prepared for arbitrary stage size. Otherwise, the application might be cropped(裁剪), or there could be garbage(垃圾) painted in the unused area of the stage.

If your application uses layouts, then you do not need to do anything. Layouts take care of resizing for you. Otherwise, implement resizing logic and listen to stage dimension changes to update the application, as shown in the simplified code in Example 3-5.

public class ResizeFriendlyApp extends Application implements 
        ChangeListener<Number> {
    private Stage stage;
    public void start(Stage stage) {
        //be resize friendly
        this.stage = stage;
        stage.widthProperty().addListener(this);
        stage.heightProperty().addListener(this);
 
        ...       
 
        //resize content
        resize(stage.getWidth(), stage.getHeight());
 
        stage.show(); 
    }
 
    private void resize(double width, double height) {
        //relayout the application to match given size
    }
 
    public void changed(ObservableValue<? extends Number> ov, 
            Number t, Number t1) {
        resize(stage.getWidth(), stage.getHeight());
    }
}


转自:http://docs.oracle.com/javafx/2/deployment/deploy_overview.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
org.elasticsearch.client.ResponseException: method [PUT], host [http://192.168.93.132:9200], URI [/TestIndex], status line [HTTP/1.1 406 Not Acceptable] {"error":"Content-Type header [application/vnd.elasticsearch+json; compatible-with=8] is not supported","status":406} at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:347) at org.elasticsearch.client.RestClient.performRequest(RestClient.java:313) at org.elasticsearch.client.RestClient.performRequest(RestClient.java:288) at co.elastic.clients.transport.rest_client.RestClientTransport.performRequest(RestClientTransport.java:146) at co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient.create(ElasticsearchIndicesClient.java:266) at co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient.create(ElasticsearchIndicesClient.java:282) at com.sora.leetcode_notebook.ElasticSearch.ElasticsearchJavaApi.createIndex(ElasticsearchJavaApi.java:52) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
06-06

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值