Javafx 如何将菜单按钮设置为始终位于其他组件(如HBox)的顶部(可拖动)
我有一个父VBox,它有一个菜单按钮和一个可拖动的HBox。当我拖动HBox时,菜单按钮没有响应(因为HBox设置在菜单按钮上)。如果HBox是可拖动的,我如何始终设置其顶部的菜单按钮 HBoxandVBoxExampleupdated.java:Javafx 如何将菜单按钮设置为始终位于其他组件(如HBox)的顶部(可拖动),javafx,Javafx,我有一个父VBox,它有一个菜单按钮和一个可拖动的HBox。当我拖动HBox时,菜单按钮没有响应(因为HBox设置在菜单按钮上)。如果HBox是可拖动的,我如何始终设置其顶部的菜单按钮 HBoxandVBoxExampleupdated.java: import DraggableNode; import javafx.scene.chart.NumberAxis; import javafx.application.Application; import javafx.geometry.In
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 This Track"));
vcfmenu.getItems().add(new CheckMenuItem("Ping To 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 All Filters"));
vcfmenu.getItems().add(new CheckMenuItem("Hides Sites not Passing All Filters"));
vbox2.getChildren().add(vcfmenu);
for (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 and VBox Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}
DragableNode.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 the current mouse X and 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 the dragging
*/
protected boolean isDragging() {
return dragging;
}
/**
* @return the view
*/
public Node getView() {
return view;
}
/**
* @param moveToFront
* the moveToFront to set
*/
public void setMoveToFront(boolean moveToFront) {
this.moveToFront = moveToFront;
}
/**
* @return the moveToFront
*/
public boolean isMoveToFront() {
return moveToFront;
}
public void removeNode(Node n) {
getChildren().remove(n);
}
}
导入javafx.event.EventHandler;
导入javafx.scene.Cursor;
导入javafx.scene.Node;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.StackPane;
公共类DragTableNode扩展StackPane{
私人双x=0;
私人双y=0;
专用双鼠标=0;
专用双鼠标=0;
私有节点视图;
私有布尔值=false;
私有布尔moveToFront=true;
私人双码=0;
私有双新闻大小=0;
公共DragTableNode(){
init();
}
公共DragTableNode(节点视图){
this.view=视图;
getChildren().add(视图);
setMouseTransparent(真);
init();
}
私有void init(){
onMousePressedProperty().set(新的EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
getScene().setCursor(Cursor.HAND);
//记录当前鼠标在节点上的X和Y位置
mousex=event.getSceneX();
mousey=event.getSceneY();
x=getLayoutX();
y=getLayoutY();
if(isMoveToFront()){
toFront();
}
}
});
onMouseDraggedProperty().set(新的EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
double offsetX=event.getSceneX()-mousex;
x+=抵销x;
双刻度x=x;
System.out.println(“:”+scaledX);
如果(缩放X>0)
{
返回;
}
setLayoutX(scaledX);
拖动=假;
mousex=event.getSceneX();
event.consume();
}
});
onMouseClickedProperty().set(新的EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
拖动=假;
}
});
}
/**
*@返回拖动
*/
受保护的布尔IsDraging(){
返回拖动;
}
/**
*@返回视图
*/
公共节点getView(){
返回视图;
}
/**
*@param moveToFront
*移动到前面设置
*/
公共无效设置moveToFront(布尔值moveToFront){
this.moveToFront=moveToFront;
}
/**
*@返回moveToFront
*/
公共布尔值isMoveToFront(){
返回到前面;
}
公共void removeNode(节点n){
getChildren().remove(n);
}
}
您可以在onMousePressedProperty的事件处理程序中将DragTableNode设置在前面。这会将DragTableNode置于其同级节点之上,并阻止菜单按钮接收鼠标输入
为了防止这种情况,我看到了两种选择:
不要通过设置moveToFront=false
将DragableNode设置到前面,或者,如果不可能
通过添加将拖动后的DragTableNode再次设置为back
onMouseReleasedProperty().set(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
toBack();
}
});
在鼠标拖动onMouseDraggedProperty时将属性设置为true
,释放鼠标时将属性设置为false
onMouseReleasedProperty().set(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
dragInProcessProperty.set(false);
}
});
onMouseReleasedProperty().set(新的EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
dragInProcessProperty.set(false);
}
});
并将ChangeListener添加到HBoxandVBoxExampleupdated中的dragInProgressProperty
node.dragInProcessProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue.booleanValue()) {
mainbox.toFront();
}
}
});
node.dragInProcessProperty().addListener(新的ChangeListener()){
@凌驾
public void changed(observeValue您将DragTableNode设置在MousePressedProperty
的事件处理程序的前面。这将DragTableNode置于其同级节点之上,并阻止菜单按钮接收鼠标输入
为了防止这种情况,我看到了两种选择:
不要通过设置moveToFront=false
将DragableNode设置到前面,或者,如果不可能
通过添加将拖动后的DragTableNode再次设置为back
onMouseReleasedProperty().set(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
toBack();
}
});
在鼠标拖动onMouseDraggedProperty时将属性设置为true
,释放鼠标时将属性设置为false
onMouseReleasedProperty().set(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
dragInProcessProperty.set(false);
}
});
onMouseReleasedProperty().set(新的EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
dragInProcessProperty.set(false);
}
});
并将ChangeListener添加到HBoxandVBoxExampleupdated中的dragInProgressProperty
node.dragInProcessProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue.booleanValue()) {
mainbox.toFront();
}
}
});
node.dragInProcessProperty().addListener(新的ChangeListener()){
@凌驾
更改公众假期(ObservableValue您想将菜单按钮
堆叠在HBox
的顶部吗?或者,您只是想将两个节点安排在彼此相邻的位置吗?@ItachiUchiha:hi…实际上,当我拖动HBox时,我的HBox容器激活,当我拖动它时,它会出现在菜单按钮上,因为我的菜单按钮没有响应ng所以我想回应它。如果hbox继续它…@ItachiUchiha:检查代码…:)如果一个节点是可拖动的,而您将其放置在另一个节点的顶部,则后者无法接收任何用户输入。如果您希望HBox不阻止鼠标事件,可以将其设置为true。但是,我在您的代码中找不到StackPane。HBox如何将自身放置在菜单按钮的顶部?是否要将菜单按钮
堆叠在eHBox
?或者,你只是想把两个节点安排在彼此相邻的位置吗?@ItachiUchiha:嗨……事实上,当我