javafx - How to set Menubutton always on top of other component like HBox (which is draggable) -


i have parent vbox holds menu button , draggable hbox. when drag hbox, menu button not responding (because hbox set on menu button). how set menu button on top of hbox if draggable?

hboxandvboxexampleupdated.java:

import draggablenode; import javafx.scene.chart.numberaxis;  import javafx.application.application; import javafx.geometry.insets;  import javafx.geometry.pos; import javafx.scene.scene; import javafx.scene.control.button; import javafx.scene.control.checkmenuitem; import javafx.scene.control.label; import javafx.scene.control.menubutton; import javafx.scene.layout.background; import javafx.scene.layout.backgroundfill; import javafx.scene.layout.border; import javafx.scene.layout.borderstroke; import javafx.scene.layout.borderstrokestyle; import javafx.scene.layout.borderwidths; import javafx.scene.layout.cornerradii; import javafx.scene.layout.hbox; import javafx.scene.layout.pane; import javafx.scene.layout.priority; import javafx.scene.layout.vbox; import javafx.scene.paint.color; import javafx.stage.stage;  public class hboxandvboxexampleupdated extends application {     static pane             pane    = new pane();     static draggablenode    node    = new draggablenode();     static numberaxis       noaxis  = new numberaxis();     static string           ref     = "hhhhhelllelelelellelellelelellelelelaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";      static hbox             nobox   = new hbox();     static numberaxis       linexaxis;     static string           style   = "-fx-border-color: blue;\n"                                             + "-fx-border-insets: 5;\n"                                             + "-fx-border-width: 3;\n"                                             + "-fx-border-style: dashed;\n";     static string           style1  = "-fx-border-color: red;\n"                                             + "-fx-border-insets: 5;\n"                                             + "-fx-border-width: 3;\n"                                             + "-fx-border-style: dashed;\n";      @override     public void start(stage primarystage) throws exception     {         pane.setstyle(style);         node.setstyle(style1);         vbox mainbox = new vbox(80);         mainbox.setalignment(pos.center);         mainbox.setpadding(new insets(50, 30, 100, 50));          vbox hbox = new vbox(60);         hbox.setalignment(pos.center); // default top_left         hbox vbox1 = new hbox();         hbox vbox2 = new hbox(10);         hbox vbox3 = new hbox(20);          button close = new button("x");         button close1 = new button("x");         menubutton vcfmenu = new menubutton("vcf");          vcfmenu.getitems().add(new checkmenuitem("about track"));         vcfmenu.getitems().add(new checkmenuitem("ping tap"));         vcfmenu.getitems().add(new checkmenuitem("edit config"));         vcfmenu.getitems().add(new checkmenuitem("delete track"));         vcfmenu.getitems().add(new checkmenuitem("save track data"));         vcfmenu.getitems().add(new checkmenuitem("show labels"));         vcfmenu.getitems().add(new checkmenuitem("hides sites passing filters"));         vcfmenu.getitems().add(new checkmenuitem("hides sites not passing filters"));          vbox2.getchildren().add(vcfmenu);          (string s : ref.split("")) {             label l = new label(s);             l.setborder(new border(                     new borderstroke(color.black, borderstrokestyle.solid, cornerradii.empty, borderwidths.default)));             l.setbackground(                     new background(                             new backgroundfill(                                     (s.equals("n") ? color.web("#dddddd")                                             : (s.equals("a") ? color.web("#00bf00")                                                     : (s.equals("c") ? color.web("#0099ff")                                                             : (s.equals("t") ? color.web("#f00")                                                                     : color.web("#d5bb04"))))),                                     cornerradii.empty, insets.empty)));             l.setalignment(pos.center);             l.setpadding(new insets(1, 4, 1, 4));              vbox1.getchildren().add(l);          }          linexaxis = new numberaxis(1, ref.length(), 4);          nobox.getchildren().add(linexaxis);         nobox.sethgrow(linexaxis, priority.always);          mainbox.getchildren().addall(vbox2);         hbox.getchildren().addall(nobox, vbox1);          node.getchildren().add(hbox);         pane.getchildren().addall(node, mainbox);         scene scene = new scene(pane, 1150, 250);          primarystage.settitle("hbox , vbox example");         primarystage.setscene(scene);         primarystage.show();     }      public static void main(string[] args)     {         application.launch(args);     } } 

draggablenode.java:

import javafx.event.eventhandler; import javafx.scene.cursor; import javafx.scene.node; import javafx.scene.input.mouseevent; import javafx.scene.layout.pane; import javafx.scene.layout.stackpane;  public class draggablenode extends stackpane {      private double  x           = 0;     private double  y           = 0;      private double  mousex      = 0;     private double  mousey      = 0;     private node    view;     private boolean dragging    = false;     private boolean movetofront = true;     private double  size        = 0;     private double  newsize     = 0;      public draggablenode() {         init();     }      public draggablenode(node view) {         this.view = view;          getchildren().add(view);         setmousetransparent(true);         init();     }      private void init() {          onmousepressedproperty().set(new eventhandler<mouseevent>() {             @override             public void handle(mouseevent event) {                 getscene().setcursor(cursor.hand);                  // record current mouse x , y position on node                 mousex = event.getscenex();                 mousey = event.getsceney();                  x = getlayoutx();                 y = getlayouty();                  if (ismovetofront()) {                     tofront();                 }             }         });          onmousedraggedproperty().set(new eventhandler<mouseevent>() {             @override             public void handle(mouseevent event) {                  double offsetx = event.getscenex() - mousex;                  x += offsetx;                  double scaledx = x;                 system.out.println(" : " + scaledx);                 if (scaledx > 0)                 {                     return;                 }                  setlayoutx(scaledx);                  dragging = false;                 mousex = event.getscenex();                  event.consume();             }         });          onmouseclickedproperty().set(new eventhandler<mouseevent>() {             @override             public void handle(mouseevent event) {                  dragging = false;             }         });      }      /**      * @return dragging      */     protected boolean isdragging() {         return dragging;     }      /**      * @return view      */     public node getview() {         return view;     }      /**      * @param movetofront      *            movetofront set      */     public void setmovetofront(boolean movetofront) {         this.movetofront = movetofront;     }      /**      * @return movetofront      */     public boolean ismovetofront() {         return movetofront;     }      public void removenode(node n) {         getchildren().remove(n);     } } 

you set draggablenode front in eventhandler onmousepressedproperty. puts draggablenode on top of sibling nodes , prevents menu button receiving mouse inputs.

to prevent this, see 2 options:

  1. don't set draggablenode front setting movetofront = false or, if isn't possible,
  2. set draggablenode again after dragging adding

    onmousereleasedproperty().set(new eventhandler<mouseevent>() {     @override     public void handle(mouseevent event) {         toback();     } }); 

    to init method of draggablenode.


for more general solution, add property draggablenode

private booleanproperty draginprocessproperty = new simplebooleanproperty(false); public booleanproperty draginprocessproperty() {     return this.draginprocessproperty; } 

set property true while dragging in onmousedraggedproperty , false when mouse released

onmousereleasedproperty().set(new eventhandler<mouseevent>() {     @override     public void handle(mouseevent event) {         draginprocessproperty.set(false);     } }); 

and add changelistener draginprogressproperty in hboxandvboxexampleupdated

node.draginprocessproperty().addlistener(new changelistener<boolean>() {     @override     public void changed(observablevalue<? extends boolean> observable, boolean oldvalue, boolean newvalue) {         if (!newvalue.booleanvalue()) {             mainbox.tofront();         }     } }); 

to set node front whenever dragging finished.


Comments