Javafx 插入新选项卡窗格后,选项卡不显示

Javafx 插入新选项卡窗格后,选项卡不显示,javafx,Javafx,我已经实现了与非常类似的拖放功能,到目前为止效果很好,但是如果将选项卡拖到主窗口/阶段之外,我还添加了一个新阶段(下面的SideStage)。问题是,该选项卡仅在我将新选项卡拖动到选项卡窗格或调整窗口大小后显示。拖放操作的主要部分发生在EventHandler中的GuiPartFactory中,get被分配给被拖动选项卡的标签。我尝试了各种尺寸分配、布局等 侧舞台课堂: private TabPane tabPane; public SideStage(double xPos, double

我已经实现了与非常类似的拖放功能,到目前为止效果很好,但是如果将选项卡拖到主窗口/阶段之外,我还添加了一个新阶段(下面的SideStage)。问题是,该选项卡仅在我将新选项卡拖动到选项卡窗格或调整窗口大小后显示。拖放操作的主要部分发生在EventHandler中的GuiPartFactory中,get被分配给被拖动选项卡的标签。我尝试了各种尺寸分配、布局等

侧舞台课堂:

private TabPane tabPane;

public SideStage(double xPos, double yPos) {

    tabPane = initTabArea();

    VBox root = new VBox(0,GuiPartFactory.initMenuAndTitle(this),tabPane);
    Scene scene = new Scene(root, 800, 600);
    setScene(scene);
    scene.setOnDragExited(new DnDExitAndEntryHandler());
    scene.setOnDragEntered(new DnDExitAndEntryHandler());
    setX(xPos);
    setY(yPos);

    ;
    initCloseWindowHandler();

}

private void initCloseWindowHandler() {
    setOnCloseRequest(new EventHandler<WindowEvent>() {

        @Override
        public void handle(WindowEvent event) {
            System.out.println("closing this sidestage");
            MainApp.sideStages.remove(SideStage.this);
        }
    });
}

private TabPane initTabArea() {
    final TabPane tabPane = GuiPartFactory.createTabPane();
    tabPane.addEventHandler(Tab.TAB_CLOSE_REQUEST_EVENT, new EventHandler<Event>() {

        @Override
        public void handle(Event event) {
            System.out.println("tab got closed mon!");
            if (tabPane.getTabs().isEmpty()) {
                SideStage.this.close();
            }
        }
    });
    VBox.setVgrow(tabPane, Priority.ALWAYS);
    return tabPane;
}

public void addTab(Tab tab) {
    tabPane.getTabs().add(tab);
}
public static ResourceBundle BUNDLE = ResourceBundle.getBundle("locales/Bundle", new Locale("en", "GB"));

public static TabPane createTabPane() {
    final TabPane tabPane = new TabPane();
    //This event gets fired when the cursor is holding a draggable object over this tabpane
    tabPane.setOnDragOver(new EventHandler<DragEvent>() {
        @Override
        public void handle(DragEvent event) {
            final Dragboard dragboard = event.getDragboard();
            if (dragboard.hasString() && dragboard.getString().equals("tab") && ((Tab) MainApp.dndTemp).getTabPane() != tabPane) {
                event.acceptTransferModes(TransferMode.MOVE);
                event.consume();
            }
        }
    });
    //This event gets fired when the cursor is releasing a draggable object over this tabpane (this gets only called if it has been accepted in the previos dragover event!)
    tabPane.setOnDragDropped(new EventHandler<DragEvent>() {
        @Override
        public void handle(DragEvent event) {
            System.out.println("dropped");
            Tab tab = (Tab) MainApp.dndTemp;
            MainApp.dndHandled = true;
            tab.getTabPane().getTabs().remove(tab);
            tabPane.getTabs().add(tab);
            tabPane.getSelectionModel().select(tab);
            event.setDropCompleted(true);
            event.consume();
        }
    });
    return tabPane;
}

public static Tab createTab(String text) {
    final Tab tab = new Tab();
    final Label label = new Label("Tab" + text);
    tab.setGraphic(label);

    StackPane pane = new StackPane();
    //need to set a real size here
    pane.setPrefSize(500, 500);
    tab.setContent(pane);

    tab.getContent().setOnDragOver(new EventHandler<DragEvent>() {
        @Override
        public void handle(DragEvent event) {
            final Dragboard dragboard = event.getDragboard();
            if (dragboard.hasString() && dragboard.getString().equals("tab") && ((Tab) MainApp.dndTemp).getTabPane() != tab.getTabPane()) {
                event.acceptTransferModes(TransferMode.MOVE);
                event.consume();
            }
        }
    });

    tab.getContent().setOnDragDropped(new EventHandler<DragEvent>() {
        @Override
        public void handle(DragEvent event) {
            System.out.println("dropped");
            Tab transferTab = (Tab) MainApp.dndTemp;
            MainApp.dndHandled = true;
            transferTab.getTabPane().getTabs().remove(transferTab);
            tab.getTabPane().getTabs().add(transferTab);
            tab.getTabPane().getSelectionModel().select(transferTab);
            event.setDropCompleted(true);
            event.consume();
        }
    });

    label.setOnDragDetected(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            Dragboard dragboard = label.startDragAndDrop(TransferMode.MOVE);
            ClipboardContent clipboardContent = new ClipboardContent();
            clipboardContent.putString("tab");
            MainApp.dndTemp = tab;
            MainApp.dndHandled = false;
            dragboard.setContent(clipboardContent);
            dragboard.setDragView(new Image("img/dragcursor.png"));
            event.consume();
        }
    });
    label.setOnDragDone(new EventHandler<DragEvent>() {

        @Override
        public void handle(DragEvent event) {
            //our dragndrop failed
            if (!MainApp.dndHandled) {
                //lets see if it failed because we dropped outside of our java-windows
                if (!MainApp.dndInside) {
                    if (!MainApp.dndTemp.equals(tab)) {
                        System.out.println("something is wrong here");
                    }
                    System.out.println("gotta make a new window!");
                    SideStage sideStage = new SideStage(event.getScreenX(), event.getScreenY());
                    MainApp.sideStages.add(sideStage);
                    //just a check to make sure we don't access a null variable
                    if (tab.getTabPane() != null) {
                        tab.getTabPane().getTabs().remove(tab);
                    }
                    sideStage.addTab(tab);
                    sideStage.sizeToScene();

                    tab.getTabPane().getSelectionModel().select(tab);
                    System.out.println("width: " + ((StackPane) tab.getContent()).getWidth());
                    System.out.println("height: " + ((StackPane) tab.getContent()).getHeight());
                    System.out.println("width: " + tab.getTabPane().getWidth());
                    System.out.println("height: " + tab.getTabPane().getHeight());
                    sideStage.show();
                }
            }
        }
    });
    return tab;
}

public static Tab createTabRandomColor(String text) {
    Random rng = new Random();
    Tab tab = GuiPartFactory.createTab(text);
    StackPane pane = (StackPane) tab.getContent();
    int red = rng.nextInt(256);
    int green = rng.nextInt(256);
    int blue = rng.nextInt(256);
    String style = String.format("-fx-background-color: rgb(%d, %d, %d);", red, green, blue);
    pane.setStyle(style);
    Label label = new Label("This is tab " + text);
    label.setStyle(String.format("-fx-text-fill: rgb(%d, %d, %d);", 256 - red, 256 - green, 256 - blue));

    pane.getChildren().add(label);

    return tab;
}

public static MenuBar initMenuAndTitle(Stage stage) {
    //setting up a window title
    stage.setTitle(BUNDLE.getString("title.name"));
    //adding the menubar
    MenuBar menuBar = new MenuBar();
    //adding the base menu entry
    Menu menuStart = new Menu(BUNDLE.getString("menu.start"));
    Menu menuView = new Menu(BUNDLE.getString("menu.view"));
    Menu menuHelp = new Menu(BUNDLE.getString("menu.help"));
    menuBar.getMenus().addAll(menuStart, menuView, menuHelp);
    //adding the menuitems inside the menus
    MenuItem aboutItem = new MenuItem(BUNDLE.getString("menu.about"));
    aboutItem.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            Dialogs popup = Dialogs.create();
            popup.title(BUNDLE.getString("menu.about.title"));
            popup.message(BUNDLE.getString("menu.about.message"));
            popup.showInformation();
        }
    });
    menuHelp.getItems().add(aboutItem);

    MenuItem exitItem = new MenuItem(BUNDLE.getString("menu.exit"));
    exitItem.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            Dialogs popup = Dialogs.create();
            popup.title(BUNDLE.getString("menu.exit.title"));
            popup.message(BUNDLE.getString("menu.exit.message"));
            popup.actions(new Action[]{YES, NO});
            Action response = popup.showConfirm();
            if(response.equals(YES)) {
                System.exit(0);
            }
        }
    });
    menuStart.getItems().add(exitItem);

    return menuBar;
}
//for handling tag drag'n'drop outside of java windows
public static Object dndTemp = null;
public static boolean dndHandled = true;
public static boolean dndInside = true;
public static Set<SideStage> sideStages = new HashSet<>();

//holding the tabs (doe)
private TabPane tabPane;

@Override
public void start(Stage stage) {
    tabPane = initTabs();
    VBox root = new VBox(0, GuiPartFactory.initMenuAndTitle(stage), tabPane);
    Scene scene = new Scene(root, 800, 600);

    stage.setScene(scene);
    stage.show();
    scene.setOnDragExited(new DnDExitAndEntryHandler());
    scene.setOnDragEntered(new DnDExitAndEntryHandler());

}



private TabPane initTabs() {
    TabPane tabPane = GuiPartFactory.createTabPane();

    Tab bedraggin = GuiPartFactory.createTab("be draggin");
    Tab beraggin = GuiPartFactory.createTab("be raggin");

    tabPane.getTabs().add(bedraggin);
    tabPane.getTabs().add(beraggin);

    for (int i = 0; i < 3; i++) {
        Tab tab = GuiPartFactory.createTabRandomColor("" + i);
        tabPane.getTabs().add(tab);
    }
    VBox.setVgrow(tabPane, Priority.ALWAYS);
    return tabPane;
}

/**
 * The main() method is ignored in correctly deployed JavaFX application.
 * main() serves only as fallback in case the application can not be
 * launched through deployment artifacts, e.g., in IDEs with limited FX
 * support. NetBeans ignores main().
 *
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

public boolean removeSideStage(SideStage sideStage) {
    return sideStages.remove(sideStage);
}

public void addTab(Tab tab) {
    tabPane.getTabs().add(tab);
}

public void removeTab(Tab tab) {
    tabPane.getTabs().remove(tab);
}

JavaFX中对可拖动选项卡的支持是Java8的一部分。链接问题包括允许拖动选项卡的选项卡窗格修补程序,您可能希望查看或使用这些修补程序或其他修补程序。感谢您的提示。通常需要多长时间才能发布下一个主要的Java版本(以及JavaFX)?如果我将选项卡拖到选项卡窗格之外的某个地方,补丁可能不会打开新窗口,我想是吧?第二个链接也有同样的问题,不幸的是,那里的下载链接不再有效。。通过评论链接的Jira问题,直接向补丁所有者提出关于补丁的问题。我明白了。谢谢但在未来的一段时间里,这是安静的:(
Platform.runLater(new Runnable() {
    @Override
    public void run() {
        sideStage.addTab(tab);
        tab.getTabPane().getSelectionModel().select(tab);
    }
});