我的上下文菜单有问题。在topic之后我发现当我尝试加载上下文菜单洞察JavaFX任务时存在限制。我测试了实现Platform.RunLater()但没有任何成功。
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;
}
其他可能的解决方案是:
一种方法是为上下文菜单定义一个自定义外观,该上下文菜单不使用PopupWindow或不在其构造函数中创建PopupWindow。
你能帮我实现吗?
P.S我测试了这段代码
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任务挂起。
答案 0 :(得分:2)
考虑以下代码,从任务创建上下文菜单。如果你摆脱了闩锁,那么在请求id时就不会构造上下文菜单。
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();
}
}