2017-03-14 7 views
0

私はツールバーの使用に問題があります。私は何をしようとしているのか、その問題を示す小さなプログラムを提供しました。基本的に私はツールバーに 'カスタム'ボタンを追加します。 「カスタム」ボタンにはXイメージがあり、ツールバーから自分自身を削除するアクションがあります。これは正常に動作します。問題は、表示する幅よりも多くのボタンがツールバーに追加されたときです。ツールバーは、他のボタンを表示するためにContextMenu /ポップアップを表示するオプションを表示するという素晴らしい動作を実行します。これもうまくいきます。この問題は、ツールバーからボタンを削除するときに発生します。ツールバーに表示されているボタンを削除するとうまくいきますが、ContextMenuからボタンを削除しようとすると、そのボタンが表示されたときにボタンが再描画されず、ボタンが削除されていないように見えます。 ContextMenuを非表示にして再表示した場合、Buttonは削除されているので、再描画の問題に過ぎません。JavaFXをツールバーから削除するコンテキストメニュー

親ノード(ツールバー)から強制的に再描画することはできますか?

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> 

答えて

0

私たちは、この非常に同じ問題を抱えています。多くの試行錯誤を経て、toolbar.getItems()からボタンを削除するだけでなく、「オーバーフロー」ボタンが生成するコンテキストメニューからボタンを削除する必要があることもわかりました。

これを試してみてください:

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

私はそれが本当にハック検索し、そのコンテキストメニューのメイクについてのインサイダーの知識を持って知っているが、それは動作します。

関連する問題