JavaFX任务中的上下文菜单

JavaFX任务中的上下文菜单,javafx,javafx-2,javafx-8,Javafx,Javafx 2,Javafx 8,在本主题之后,我想在JavaFX任务中创建上下文菜单。我测试了这段代码: static private StringBuilder stringBuilder = new StringBuilder(); private static ContextMenu contextMenu; private static CountDownLatch menuCreated = new CountDownLatch(1); static synchronized void w

在本主题之后,我想在JavaFX任务中创建上下文菜单。我测试了这段代码:

static private StringBuilder stringBuilder = new StringBuilder();

    private static ContextMenu contextMenu;
    private static CountDownLatch menuCreated = new CountDownLatch(1);

    static synchronized void writeString(String s)
    {
        stringBuilder.append(s).append("\n");
    }

    public static BorderPane init(BorderPane bp) throws Exception
    {

        System.out.println("***** CALLED");

        Task task = new Task()
        {
            @Override
            protected Void call() throws Exception
            {
                writeString("Task started");

                writeString(Thread.currentThread().getName() + " is fx thread: "
                    + Platform.isFxApplicationThread());

                Platform.runLater(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        writeString(Thread.currentThread().getName() + " is fx thread: "
                            + Platform.isFxApplicationThread());
                        try
                        {
                            contextMenu = new ContextMenu();
                            contextMenu.setId("Test ID");
                            writeString("Created context menu");
                            menuCreated.countDown();
                        }
                        catch (Exception ex)
                        {
                            writeString(ex.getMessage());
                            ex.printStackTrace();
                        }
                        finally
                        {
                            writeString("Test");
                        }
                    }
                });

                writeString("Task finished");
                return null;
            }
        };

        new Thread(task).start();

        MenuItem item1 = new MenuItem("About");
        item1.setOnAction(new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(ActionEvent e)
            {
                System.out.println("About");
            }
        });
        MenuItem item2 = new MenuItem("Preferences");
        item2.setOnAction(new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(ActionEvent e)
            {
                System.out.println("Preferences");
            }
        });
        MenuItem item3 = new MenuItem("Close");
        item3.setOnAction(new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(ActionEvent e)
            {
                //flow.getChildren().remove(bp);
            }
        });
        contextMenu.getItems().addAll(item1, item2, item3);

        bp.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()
        {
            @Override
            public void handle(ContextMenuEvent event)
            {
                //contextMenu.hide();

                System.out.println("*********************** Shown Context Menu ***!!!!!!!");
                contextMenu.show(bp, event.getScreenX(), event.getScreenY());
                event.consume();
            }
        });

        bp.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent event)
            {
                contextMenu.hide();
            }
        });

        menuCreated.await();

        return bp;
    }
静态私有StringBuilder StringBuilder=新StringBuilder();
私有静态上下文菜单上下文菜单;
private static CountDownLatch menuCreated=新建CountDownLatch(1);
静态同步的void writeString(字符串s)
{
stringBuilder.append.append(“\n”);
}
公共静态BorderPane init(BorderPane bp)引发异常
{
System.out.println(“******称为”);
任务=新任务()
{
@凌驾
受保护的Void调用()引发异常
{
writeString(“任务已启动”);
writeString(Thread.currentThread().getName()+“是fx线程:”
+Platform.isFxApplicationThread());
Platform.runLater(新的Runnable()
{
@凌驾
公开募捐
{
writeString(Thread.currentThread().getName()+“是fx线程:”
+Platform.isFxApplicationThread());
尝试
{
contextMenu=新建contextMenu();
setId(“测试ID”);
writeString(“创建的上下文菜单”);
menuCreated.countDown();
}
捕获(例外情况除外)
{
writeString(例如getMessage());
例如printStackTrace();
}
最后
{
书面限制(“测试”);
}
}
});
writeString(“任务完成”);
返回null;
}
};
新线程(任务).start();
MenuItem1=新MenuItem(“关于”);
item1.setOnAction(新的EventHandler()
{
@凌驾
公共无效句柄(ActionEvent e)
{
System.out.println(“关于”);
}
});
MenuItem2=新MenuItem(“首选项”);
item2.setOnAction(新的EventHandler()
{
@凌驾
公共无效句柄(ActionEvent e)
{
System.out.println(“首选项”);
}
});
MenuItem3=新MenuItem(“关闭”);
item3.setOnAction(新的EventHandler()
{
@凌驾
公共无效句柄(ActionEvent e)
{
//flow.getChildren().remove(bp);
}
});
contextMenu.getItems().addAll(item1、item2、item3);
bp.setOnContextMenuRequested(新事件处理程序()
{
@凌驾
公共无效句柄(ContextMenuEvent事件)
{
//contextMenu.hide();
System.out.println(“**********************显示的上下文菜单***!!!!!!!!!!!”;
show(bp,event.getScreenX(),event.getScreenY());
event.consume();
}
});
bp.addEventHandler(按下MouseEvent.MOUSE_,新建EventHandler())
{
@凌驾
公共无效句柄(MouseeEvent事件)
{
contextMenu.hide();
}
});
菜单已创建。等待();
返回bp;
}

通过这段代码,我为BorderPane设置了上下文菜单。当我用鼠标右键单击时,我会看到调试消息**********************显示的上下文菜单***!!!!!!!但是没有上下文菜单。你能帮我修复这个代码吗?

这个代码毫无意义。为什么要创建一个简单地将其工作委托回FX应用程序线程的任务?您也可以简单地在FX应用程序线程中开始工作。你为什么要在任务中创建ContextMenu?因为当我尝试创建ContextMenu insight任务时,JavaFX有一个限制,我想找到解决这个问题的方法。“限制”是你不能在不同的线程上创建ContextMenu。但您只需要在单独的线程上执行需要很长时间的操作,并且创建ContextMenu不需要很长时间即可执行。为什么要在任务中创建上下文菜单?