首页 > 解决方案 > 如何在 StackPane 中重新定位 VBox

问题描述

我希望鼠标在几个计时码表上跟随垂直时间标记以指示时间戳,但 setLayoutX() 或 relocate() 对 StackPane 完全没有影响。

我写了以下最小的可重现示例:

public class VerticalTimeMarkIsNotRelocated extends Application {

   @FXML private StackPane timeMarkContainer;
   @FXML private Label     label;
   @FXML private VBox      timeMark;

   @FXML
   private void initialize() {
      StackPane.clearConstraints( timeMark );
      StackPane.setAlignment( label, Pos.BOTTOM_CENTER );
   }

   @FXML
   private void moveTimeMark( MouseEvent e ) {
      final double x = e.getX();
      System.err.printf( "%7.2f\n", x );
      timeMark.relocate( x, 0 );
   }

   @Override
   public void start( Stage primaryStage ) throws Exception {
      final Class<?> clazz = getClass();
      primaryStage.setScene( new Scene( FXMLLoader.load( clazz.getResource( clazz.getSimpleName() + ".fxml" ))));
      primaryStage.show();
   }

   public static void main( String[] args ) {
      launch( args );
   }
}

VerticalTimeMarkIsNotRelocated.fxml:

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

<?import java.net.URL?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>

<StackPane xmlns:fx="http://javafx.com/fxml" fx:controller="so.VerticalTimeMarkIsNotRelocated"
   fx:id="timeMarkContainer" prefWidth="420" prefHeight="140" onMouseMoved="#moveTimeMark">
   <stylesheets>
      <URL value="@VerticalTimeMarkIsNotRelocated.css" />
   </stylesheets>
   <Label fx:id="label" text="Replacement for several chronogram widgets" />
   <VBox  fx:id="timeMark" minWidth="1.0" maxWidth="1.0" />
</StackPane>

VerticalTimeMarkIsNotRelocated.css:

#timeMark {
  -fx-background-color: red;
}
#label {
  -fx-background-color: bisque;
  -fx-padding: 40px;
}

在以下屏幕快照中,我们可以在 Eclipse 控制台中看到鼠标移动了,但垂直的红色标记仍位于 StackPane 的中间:

垂直时标未重定位

标签: javajavafxlayout

解决方案


以编程方式设置边距并使用插入(双顶,双右,双底,双左)

   @FXML
   private void moveTimeMark( MouseEvent e ) {
      final double x = e.getX();
      System.err.printf( "%7.2f\n", x );
      StackPane.setMargin(timeMark, new Insets(0,x,0,0));
   }

推荐阅读