- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个主题存在于无数“在长时间持续调用耗时的内容(服务器)期间不阻塞 JavaFX UI”的文章中。我知道这一点,我用谷歌搜索并尝试了很多。大多数“互联网”解释说,由JavaFX事件引起的持久调用需要在额外的线程中进行。线程完成后,您可以通过 Platform.runLater() 使用结果更新 FX UI。大多数 FX 库都用复杂的代码结构封装了这一点(非常酷的东西)。我当前的问题是:我们正在将 Swing 富客户端迁移到 JavaFX。它是一个巨大的客户端,因此我们必须不断地在其中包含/替换 JavaFX UI,直到它成为一个完整的 FX 客户端。客户端中有一些功能会执行服务器调用,并且必须等待用户才能继续其工作。服务器使用带有无状态 session bean 和接口(interface)的 JEE6。这些接口(interface)对于客户端来说是已知的,并且通过我们自己的一个小库,我们实现了一个小代理,对客户端隐藏了通信层。客户端只需使用库创建一个“RemoteProxy”,然后调用远程接口(interface),库将调用传播到服务器。调用该方法并将结果或异常传输回客户端。对于客户端来说,这看起来就像本地调用。问题就在这里。典型的代码片段如下所示:
...
ServerRemoteInterface myServerRemoteProxy = Helper.getProxyForInterface(ServerRemoteInterface.class) ;
...
ComplexResult result = myServerRemoteProxy.doThingsOnServer(SerializableParameter p1 ...)
doSomethingUsefull() ;
对服务器的调用在 Swing UI 线程中触发(通过监听器)。它停止程序(监听器代码)的执行,尽管它是在额外的线程中完成的。服务器返回后调用“doSomethingUsefull()”。开发人员不必关心这里的线程。它是如何实现的?通过使用“旋转库”(http://spin.sourceforge.net/)。它对 Swing EDT 做了一些巧妙的处理。另一种选择是使用模态对话框,但我们决定不使用额外的窗口,而是使用玻璃 Pane 来禁用一些 UI 组件。
这么长的解释和简短的问题......JavaFX 是否有类似的东西可以帮助我们无缝调用服务器、停止程序执行直到它返回并且不阻塞 JavaFX UI?如果它可以与 Java Swing 部分代码一起工作那就最好了。
编辑...添加一个非常压缩的示例来演示隐藏 JDialog 的使用。
我们需要服务器远程接口(interface)。任何接口(interface)都可以。
public interface ServerRemoteInterface
{
public String method1() ; // String result in our case for test purposes
public String method2() ; // Exceptions would also be possible.
}
然后我们需要代理调用处理程序
public class ServerProxy implements InvocationHandler
{
public Object result;
JDialog modalDialog = new JDialog((Frame)null, true);
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
ServerCallHelper serverThread = new ServerCallHelper(args, method) ;
modalDialog.setLocation(4000, 5000); // as if using Spin library. Here we use the dialog to block in a location off the screen.
serverThread.start();
modalDialog.setVisible(true) ;
return result;
}
class ServerCallHelper extends Thread
{
Object[] args;
Method method;
public ServerCallHelper(Object[] args, Method method)
{
this.args = args;
this.method = method;
}
public void run()
{
// do a server call via rmi or tunnel it via http, REST or whatever and provide the call parameters. On the server side there must be a receiver propagating the call to the wanted session bean.
// here we just do a simulation
try
{
Thread.sleep(3000);
} catch (InterruptedException e)
{
// interupt is ok here.
}
// now hand the result from the call back. we simulate a fix result
// We also could have caught the Exception and deal with it.
result = "Simulated Result" ;
// Since we are in the worker thread => inform EDT To close the dialog.
SwingUtilities.invokeLater(()->modalDialog.setVisible(false));
}
}
}
最后是一些展示功能的代码
public class SampleUI extends JFrame
{
JButton serverCallButton = new JButton("Call server") ;
JLabel resultLabel = new JLabel("No result so far") ;
public SampleUI()
{
JPanel cont = new JPanel() ;
cont.add(serverCallButton) ;
cont.add(resultLabel) ;
this.setContentPane(cont);
serverCallButton.addActionListener((e)->processServerButtonCall());
}
private void processServerButtonCall()
{
ServerRemoteInterface serverAccess = (ServerRemoteInterface) Proxy.newProxyInstance(SampleUI.class.getClassLoader(), new Class[]{ServerRemoteInterface.class}, new ServerProxy());
String result = serverAccess.method1() ;
resultLabel.setText(result);
}
public static void main(String[] args)
{
SampleUI sampleUI = new SampleUI() ;
sampleUI.pack();
sampleUI.setVisible(true);
}
}
这个例子非常压缩,但应该展示原理。作为开发人员,我不必关心对服务器的调用实际上是服务器调用。对我来说,这就像调用本地电话一样。我什至不必关心我是否在 EDT 主题中,因为我就是这样。正如我所说,在 FX 中,它的工作方式与模态阶段相同。我尝试将其设置为不透明 0.0 => 无论如何它都没有绘制。这有效。
问题仍然存在:有没有办法绕过额外的 JDialog 或 Stage ?
最佳答案
如果我正确理解你的意图,这是 Future 的一个用例:
CompletableFuture.supplyAsync(() -> myServerRemoteProxy.doThingsOnServer(...))
.thenAccept(result -> doSomethingUseful(result));
服务器调用和 doSomethingUseful
都会在另一个线程中执行,因此如果需要,您需要在 doSomethingUseful
中使用 Platform.runLater
访问场景图。
关于JavaFX 阻止 UI(和代码)直到服务器调用完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27015463/
谁能解释一下 Server.MapPath(".")、Server.MapPath("~")、Server.MapPath(@"之间的区别\") 和 Server.MapPath("/")? 最佳答案
我不知道,为什么我们要使用 Server.UrlEncode() & Server.UrlDecode()?!在 QueryString 中我们看到 URL 中的任何内容,那么为什么我们要对它们进行编
我已经通过 WHM 在我的一个域上安装了 ssl 证书。网站正在使用 https://xyz.com . 但是它不适用于 https://www.xyz.com .我已经检查了证书,它也适用于 www
我已经使用 WMI 检测操作系统上是否存在防病毒软件,itz 正常工作并通过使用命名空间向我显示防病毒信息,例如 win xp 和 window7 上的名称和实例 ID:\root\SecurityC
我们有 hive 0.10 版本,我们想知道是否应该使用 Hive Server 1 或 Hive Server2。另一个问题是连接到在端口 10000 上运行的 Hive 服务器,使用 3rd 方工
我想在 C++ 中使用 Windows Server API 设置一个 HTTPS 服务器,我使用了示例代码,它在 HTTP 上工作正常,但我就是不能让它在 HTTPS 上工作。 (我不想要客户端 S
我写了一个非常基本的类来发送电子邮件。我用 smtp 服务器对其进行了测试,它工作正常,但是当我尝试使用我公司的交换服务器时,它给出了这个异常: SMTP 服务器需要安全连接或客户端未通过身份验证。服
我的应用程序包含一个“网关”DataSnap REST 服务器,它是所有客户端的第一个访问点。根据客户端在请求中传递的用户名(基本身份验证),请求需要重定向到另一个 DataSnap 服务器。我的问题
我有一个 Tomcat 服务器和一个 Glassfish4 服务器。我的 Servlet 在 Tomcat 服务器上启动得很好,但在 Glassfish4 服务器上给我一个“HTTP Status 4
我在 vmware 上创建了一个 ubuntu 服务器。我用它作为文件服务器。如果我通过托管虚拟机的计算机进行连接,则可以访问它。我无法从同一网络上的其他计算机执行此操作。提前致谢! 最佳答案 首先确
如何重启 Rails 服务器?我从 开始 rails server -d 所以服务器是分离的 我知道的唯一方法就是去做ps 辅助 | grep rails 并 kill -9关于过程#但是像这样杀死进
我实际上正在尝试找到编写一个简单的 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的服务器。我只关心XMPP的核心功能(状态、消息传递、群组消息传递)。目前还在学习 XMPP 协议(proto
我实际上正在尝试找到编写简单 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的方法。我只关心 XMPP 的核心功能(统计、消息、组消息)。目前也在学习 XMPP 协议(protocol),所以
我们正在尝试从 Java JAX-RS 适配器访问 SOAP 1.1 Web 服务。 我们正在使用从 WSDL 生成的 SOAP 客户端。 但是当解码 SOAP 故障时,我们得到以下异常: ... C
目前,我和许多其他人正在多个平台(Windows、OS X 和可能的 Linux)上使用 Python HTTP 服务器。我们正在使用 Python HTTP 服务器来测试 JavaScript 游戏
我有一个连续运行的服务器程序(C#/.NET 2.0 on Linux with mono),我想从 PHP 脚本连接到它以在网站上显示状态信息。 目的是创建一个(某种)实时浏览器游戏(无 Flash
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
我们刚刚将测试 Web 服务器从 Server 2008 升级到 Server 2012 R2。我们有一个部署我们网站的批处理脚本。当它将站点推送到服务器时,它现在失败了。奇怪的是,我可以使用相同的发
建议一些加载SpagoBI服务器的方法,我尝试了所有方法来解析spagobi服务器。在 Catalina 中,错误是 - * SEVERE: Unable to process Jar entry [
当我们点击应用程序服务器(apache tomcat)时,它会创建一个线程来处理我们的请求并与 tomcat 连接,建立连接,tomcat 创建另一个线程来处理请求并将其传递给连接,连接线程将其传递给
我是一名优秀的程序员,十分优秀!