2017-03-14 3 views
0

Ich habe ein Problem mit meiner Verwendung der Toolbar. Ich habe ein kleines Programm zur Verfügung gestellt, das demonstriert, was ich versuche und das Problem. Grundsätzlich füge ich einen 'benutzerdefinierten' Button zu einer Toolbar hinzu. Die 'benutzerdefinierten' Schaltflächen haben ein X-Bild und eine Aktion, mit der sie sich aus der Symbolleiste entfernen können. Das funktioniert gut. Das Problem ist, wenn der Symbolleiste mehr Schaltflächen hinzugefügt werden als Breite, um sie anzuzeigen. Die Symbolleiste führt ein nettes Verhalten aus, indem sie die Option zeigt, ein ContextMenu/Popup anzuzeigen, um die anderen Schaltflächen anzuzeigen. Dies funktioniert auch gut. Das Problem tritt auf, wenn Sie die Schaltflächen aus der Symbolleiste entfernen. Entfernen von Schaltflächen, die in der Symbolleiste sichtbar sind, funktioniert gut. Wenn Sie jedoch versuchen, Schaltflächen aus dem ContextMenu zu entfernen, werden sie nicht neu gezeichnet, wenn sie sichtbar gemacht werden. Daher sieht die Schaltfläche so aus, als wäre sie nicht entfernt worden. Wenn das ContextMenu ausgeblendet und dann wieder angezeigt wird, wurde die Schaltfläche entfernt, sodass es sich nur um ein Problem beim erneuten Zeichnen handelt.JavaFX Knoten aus ToolBar ContextMenu entfernen

Gibt es auf jeden Fall kann ich erzwingen, dass dies vom Elternknoten (der Toolbar) nach unten neu zeichnen?

package ToolbarTest; 

import java.net.URL; 
import java.util.LinkedHashMap; 
import java.util.ResourceBundle; 

import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.Node; 
import javafx.scene.control.Button; 
import javafx.scene.control.ToggleButton; 
import javafx.scene.control.ToolBar; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.layout.BorderPane; 

public class ToolbarHolderController implements Initializable { 

    @FXML 
    ToolBar toolBar; 
    @FXML 
    BorderPane borderPane; 
    @FXML 
    Button addButton; 
    @FXML 
    Button removeButton; 
    @FXML 
    private LinkedHashMap<String, ToggleButton> toggleButtonHash = new LinkedHashMap<>(); 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 

     IntegerProperty i = new SimpleIntegerProperty(0); 

     addButton.setOnAction(e -> { 
      ImageView closeImageView = new ImageView(new Image(getClass().getResource("tabclose2.png").toString())); 
      String text="B:" + i.get(); 
      RemoveableToggleButton tButton = new RemoveableToggleButton(text, closeImageView, new EventHandler<ActionEvent>() { 
       @Override 
       public void handle(ActionEvent e) { 
        if (toggleButtonHash.containsKey(text)) { 
         toolBar.getItems().remove(toggleButtonHash.get(text)); 
         toggleButtonHash.remove(text); 
        } 
        e.consume(); 
       } 
      }); 
      toolBar.getItems().add(tButton); 
      toggleButtonHash.put(text, tButton); 
      i.set(i.get() + 1); 
     }); 

     removeButton.setOnAction(e->{ 
       toolBar.getItems().remove(toolBar.getItems().size()-1); 
      } 
     ); 
    } 

    class RemoveableToggleButton extends ToggleButton { 

     private Button close = new Button(); 

     public RemoveableToggleButton(String text, Node graphic, EventHandler<ActionEvent> closeEvent) { 
      this.close.setGraphic(graphic); 
      this.close.setOnAction(closeEvent); 
      this.close.setMouseTransparent(false); 
      this.textProperty().set(text); 
      this.setGraphic(close); 
     } 

    } 
} 

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> 

Antwort

0

Wir haben diese sehr gleiche Problem. Durch eine Menge Versuch und Irrtum konnte ich feststellen, dass Sie nicht nur die Schaltfläche aus der toolbar.getItems() entfernen müssen, sondern auch aus dem Kontextmenü, dass die "Überlauf" -Schaltfläche generiert.

Try this:

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

Ich weiß es wirklich Hacky aussieht und Insider-Wissen über das Make-up dieses Kontextmenü, aber es funktioniert.