上下文菜单洞察JavaFX任务 [英] Context menu insight JavaFX Task

查看:183
本文介绍了上下文菜单洞察JavaFX任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的上下文菜单有问题。在主题之后,我发现当我尝试加载上下文菜单洞察JavaFX任务时存在限制。我测试了实现Platform.RunLater()但没有任何成功。

I have a problem with Context menu. Following this topic I found that there is a limitation when I try to load Context menu insight JavaFX Task. I tested to implement Platform.RunLater() but without any success.

static ContextMenu contextMenuPanel;  
    public static BorderPane stageContextMenu(BorderPane bp)  
    {  
        Platform.runLater(new Runnable() {  
            @Override public void run() {  
                contextMenuPanel = new ContextMenu();  
            }  
        });  
        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);  
            }  
        });  
        contextMenuPanel.getItems().addAll(item1, item2, item3);  
        bp.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()  
        {  
            @Override  
            public void handle(ContextMenuEvent event)  
            {  
                //contextMenu.hide();  
                contextMenuPanel.show(bp, event.getScreenX(), event.getScreenY());  
                event.consume();  
            }  
        });  
        bp.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>()  
        {  
            @Override  
            public void handle(MouseEvent event)  
            {  
                contextMenuPanel.hide();  
            }  
        });  
        return bp;  
    }  

其他可能的解决方案是:

Other possible solution is:

一种方法是为上下文菜单定义一个自定义皮肤,该菜单不使用PopupWindow或不在其构造函数中创建PopupWindow。

你能帮我实现吗?

PS我测试了这段代码

P.S I tested this code

static private StringBuilder stringBuilder = new StringBuilder();

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

    static ContextMenu contextMenuPanel;

    public static BorderPane stageContextMenu(BorderPane bp) throws InterruptedException
    {

        new Button();

        Task task = new Task()
        {
            @Override
            protected Void call() throws Exception
            {


                Platform.runLater(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        try
                        {
                            contextMenu = new ContextMenu();
                            contextMenu.setId("Test ID");
                            menuCreated.countDown();
                        }
                        catch (Exception ex)
                        {
                            ex.printStackTrace();
                        }
                        finally
                        {
                        }
                    }
                });

                return null;
            }
        };

        new Thread(task).start();

        menuCreated.await();

        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);
            }
        });
        contextMenuPanel.getItems().addAll(item1, item2, item3);

        bp.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()
        {
            @Override
            public void handle(ContextMenuEvent event)
            {
                //contextMenu.hide();
                contextMenuPanel.show(bp, event.getScreenX(), event.getScreenY());
                event.consume();
            }
        });

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

        return bp;
    }

但结果不成功 - JavaFX任务挂起。

But the result is unsuccessful - JavaFX Task hangs.

推荐答案

考虑以下代码,从任务创建上下文菜单。如果你摆脱了闩锁,在请求id时就不会构造上下文菜单。

Consider the following code which creates a context menu from task. If you get rid of the latch the context menu wont be constructed at the time when its id is requested.

import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.stage.Stage;

import java.util.concurrent.CountDownLatch;

public class InitThreadTest extends Application {

    static private StringBuilder stringBuilder = new StringBuilder();

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

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

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

    @Override public void init() throws Exception {
        new Button();

        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();

        menuCreated.await();

    }
    @Override public void start(Stage s) {

        System.out.println(stringBuilder.toString());
        System.out.println("Context menu is " + ((contextMenu == null) ? null : contextMenu.getId()));

        Platform.exit();
    }
}

这篇关于上下文菜单洞察JavaFX任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆