插入新TabPane后,Tab未显示

时间:2014-08-06 18:48:39

标签: javafx

我已经实现了与How to drag and drop tab nodes between tab panes非常相似的拖放功能,到目前为止工作正常,但如果选项卡被拖到外面,我还会添加一个新的Stage(下面的SideStage)主窗口/阶段。问题是,Tab只是在我将一个新Tab拖到TabPane或者我调整窗口大小后才显示。拖动动作的主要部分发生在EventHandler中的GuiPartFactory中,它被分配给被拖动的Tab的Label。我尝试了各种大小的分配,requestLayout等等。

Sidestage 类:

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

GuiPartFactory 类:

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;
}

最后是 MainApp 类:

//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);
}

编辑:临时解决方法是将实际添加的标签添加到新的TabPane中,并将其添加到runnable中。但我认为这是一个相当糟糕的解决方案:

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        sideStage.addTab(tab);
        tab.getTabPane().getSelectionModel().select(tab);
    }
});

0 个答案:

没有答案