JavaFX从工具栏上下文菜单中删除节点

JavaFX从工具栏上下文菜单中删除节点,java,javafx-8,Java,Javafx 8,我在使用工具栏时遇到问题。我提供了一个小程序,演示了我正在尝试做的事情和问题。基本上,我在工具栏上添加了一个“自定义”按钮。“自定义”按钮上有一个X图像,它们有一个允许从工具栏中删除自己的操作。这个很好用。问题是,当添加到工具栏的按钮超过显示按钮的宽度时,工具栏会显示查看上下文菜单/弹出窗口以显示其他按钮的选项。这也很有效。从工具栏中删除按钮时会出现问题。删除工具栏上可见的按钮效果很好,但是如果尝试从上下文菜单中删除按钮,当按钮变为可见时,它不会重新绘制自身,因此按钮看起来好像没有被删除。如果C

我在使用工具栏时遇到问题。我提供了一个小程序,演示了我正在尝试做的事情和问题。基本上,我在工具栏上添加了一个“自定义”按钮。“自定义”按钮上有一个X图像,它们有一个允许从工具栏中删除自己的操作。这个很好用。问题是,当添加到工具栏的按钮超过显示按钮的宽度时,工具栏会显示查看上下文菜单/弹出窗口以显示其他按钮的选项。这也很有效。从工具栏中删除按钮时会出现问题。删除工具栏上可见的按钮效果很好,但是如果尝试从上下文菜单中删除按钮,当按钮变为可见时,它不会重新绘制自身,因此按钮看起来好像没有被删除。如果ContextMenu被隐藏,然后重新显示,则按钮已被删除,因此这只是一个重绘问题

我是否可以强制从父节点(工具栏)向下重画

package测试;
导入java.net.URL;
导入java.util.LinkedHashMap;
导入java.util.ResourceBundle;
导入javafx.beans.property.IntegerProperty;
导入javafx.beans.property.SimpleIntegerProperty;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.fxml.fxml;
导入javafx.fxml.Initializable;
导入javafx.scene.Node;
导入javafx.scene.control.Button;
导入javafx.scene.control.ToggleButton;
导入javafx.scene.control.ToolBar;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.BorderPane;
公共类ToolbarHolderController实现可初始化{
@FXML
工具栏;
@FXML
边界窗格边界窗格;
@FXML
按钮添加按钮;
@FXML
按钮移除按钮;
@FXML
私有LinkedHashMap toggleButtonHash=新LinkedHashMap();
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
IntegerProperty i=新的SimpleIntegerProperty(0);
addButton.setOnAction(e->{
ImageView closeImageView=newImageView(新图像(getClass().getResource(“tabclose2.png”).toString());
String text=“B:”+i.get();
RemoveableToggleButton tButton=新建RemoveableToggleButton(文本,closeImageView,new EventHandler()){
@凌驾
公共无效句柄(ActionEvent e){
if(切换按钮hash.containsKey(文本)){
toolBar.getItems().remove(toggleButtonHash.get(text));
toggleButtonHash.remove(文本);
}
e、 消费();
}
});
toolBar.getItems().add(tButton);
toggleButtonHash.put(文本,tButton);
i、 set(i.get()+1);
});
移除按钮。设置操作(e->{
toolBar.getItems().remove(toolBar.getItems().size()-1);
}
);
}
类RemoveableToggleButton扩展了ToggleButton{
私有按钮关闭=新按钮();
public RemoveableToggleButton(字符串文本、节点图形、EventHandler closeEvent){
this.close.setGraphic(图形);
this.close.setOnAction(closeEvent);
this.close.setMouseTransparent(false);
this.textProperty().set(text);
这个。设置图形(关闭);
}
}
}
ToolBarHolder.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane fx:id="borderPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ToolbarTest.ToolbarHolderController">
   <top>
      <ToolBar fx:id="toolBar" prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
   </top>
   <center>
      <HBox spacing="5.0" BorderPane.alignment="CENTER_LEFT">
         <children>
            <Button fx:id="addButton" mnemonicParsing="false" text="add" />
             <Button fx:id="removeButton" mnemonicParsing="false" text="remove" />
         </children>
         <padding>
            <Insets bottom="5.0" left="5.0" top="5.0" />
         </padding>
      </HBox>
   </center>
</BorderPane>

我们也有同样的问题。通过一系列的尝试和错误,我发现您不仅需要从toolbar.getItems()中删除该按钮,还需要从“overflow”按钮生成的上下文菜单中删除该按钮

试试这个:

// if the button is inside of a context menu, remove it from there as well
if (buttonToClose.getParent() != null &&
    buttonToClose.getParent().getParent() != null &&
    buttonToClose.getParent().getParent().getParent() != null &&
    buttonToClose.getParent().getParent().getParent() instanceof ContextMenuContent) {

    ContextMenuContent contextMenuContent = buttonToClose.getParent().getParent().getParent();
    contextMenuContent.getItemsContainer().getChildren().remove(buttonToClose.getParent());
}

我知道它看起来很粗糙,并且对上下文菜单的组成有内部了解,但它很有效。

我唯一需要做的就是将其转换为ContextMenuContent,非常感谢您发布此消息:)
// if the button is inside of a context menu, remove it from there as well
if (buttonToClose.getParent() != null &&
    buttonToClose.getParent().getParent() != null &&
    buttonToClose.getParent().getParent().getParent() != null &&
    buttonToClose.getParent().getParent().getParent() instanceof ContextMenuContent) {

    ContextMenuContent contextMenuContent = buttonToClose.getParent().getParent().getParent();
    contextMenuContent.getItemsContainer().getChildren().remove(buttonToClose.getParent());
}