繁体   English   中英

使用translateX()和translateY()时,窗格布局中的JavaFX文本与其他元素重叠

[英]JavaFX Text inside Pane Layout is overlapping other Elements when using translateX() and translateY()

下图是对正在发生的事情的描述:

在此输入图像描述


我有一个包含TextPane ,我正在使用下面的代码来制作Textmarquee like effect 因此,当Pane没有足够的空间来显示文本时,动画开始播放,文本必须来回移动,以便用户可以完整地看到它。

问题是我在使用setTranslateX()向左移动时期望文本消失而不与其他元素重叠。例如,这里重叠StackPane在左边。

代码来自 - > JavaFX Marquee Animation问题。

  • 为什么会这样?
  • 我需要一个解决方案和简要说明:)

以下是代码:

Marquee.java [类]:

import java.io.IOException;

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.InvalidationListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.util.Duration;

/**
 * When the screen element is not big enough to show the text then an animation
 * will start automatically
 * 
 *
 */
public class Marquee extends Pane{

    @FXML
    private Text text;

    // minimum distance to Pane bounds
    private static final double OFFSET = 5;

    private Timeline timeline = new Timeline();

    /**
     * Constructor
     */
    public Marquee() {

        // FXMLLOADER
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Marquee.fxml"));
            loader.setController(this);
            loader.setRoot(this);
            loader.load();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }


    /**
     * Called when FXML is loaded
     */
    @FXML
    public void initialize() {

        startAnimation();
    }

    /**
     * This method changes the text of the Marquee
     * 
     * @param value
     * @return this
     */
    public Marquee setText(String value) {

        // text
        text.setText(value);

        return this;
    }

    /**
     * This method starts the Animation of the marquee
     */
    private final void startAnimation() {

        // KeyFrame
        KeyFrame updateFrame = new KeyFrame(Duration.millis(35), new EventHandler<ActionEvent>() {

            private boolean rightMovement;

              @Override
                public void handle(ActionEvent event) {
                    double textWidth = text.getLayoutBounds().getWidth();
                    double paneWidth = getWidth();
                    double layoutX = text.getLayoutX();

                    if (2 * OFFSET + textWidth <= paneWidth && layoutX >= OFFSET) {
                        // stop, if the pane is large enough and the position is correct
                        text.setLayoutX(OFFSET);
                        timeline.stop();
                    } else {
                        if ((rightMovement && layoutX >= OFFSET) || (!rightMovement && layoutX + textWidth + OFFSET <= paneWidth)) {
                            // invert movement, if bounds are reached
                            rightMovement = !rightMovement;
                        }

                        // update position
                        if (rightMovement) {
                            layoutX += 1;
                        } else {
                            layoutX -= 1;
                        }
                        text.setLayoutX(layoutX);
                    }
                }
        });
        timeline.getKeyFrames().add(updateFrame);
        timeline.setCycleCount(Animation.INDEFINITE);

        // listen to bound changes of the elements to start/stop the
        // animation
        InvalidationListener listener = o -> {
            double textWidth = text.getLayoutBounds().getWidth();
            double paneWidth = getWidth();
            if (textWidth + 2 * OFFSET > paneWidth && timeline.getStatus() != Animation.Status.RUNNING)
                timeline.play();
        };

        text.layoutBoundsProperty().addListener(listener);
        widthProperty().addListener(listener);

    }

}

Marquee.fxml

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

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Text?>

<fx:root maxHeight="25.0" minHeight="25.0" prefHeight="25.0" prefWidth="100.0" style="-fx-border-color: orange;" type="Pane" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Text fx:id="text" layoutX="5.0" layoutY="17.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" />
   </children>
</fx:root>

最后是Main.java [class]

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {

        Scene scene = new Scene(new Marquee().setText("Extra Biiggggggg Textttt"), 300, 300);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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


Fabians回答后编辑:

.fxml现在是:

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

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.shape.Rectangle?>

<fx:root fx:id="root" maxHeight="25.0" minHeight="25.0" prefHeight="25.0" prefWidth="100.0" style="-fx-border-color: orange; -fx-background-color: white;" type="Pane" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
  <children>
     <Text fx:id="text" layoutX="5.0" layoutY="17.0" strokeType="OUTSIDE" strokeWidth="0.0" style="-fx-text-fill: black; -fx-font-weight: bold;" text="Stopped" />
  </children>
  <clip>
     <Rectangle width="${root.width}" height="${root.height}"/>
  </clip>
</fx:root>

为什么这样做?

默认情况下,JavaFX还会在节点边界之外绘制子节点。

如何解决?

使用父级的clip属性剪切Pane边界处的内容:

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

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.shape.Rectangle?>

<fx:root xmlns:fx="http://javafx.com/fxml/1" fx:id="root" maxHeight="25.0" minHeight="25.0" prefHeight="25.0" prefWidth="100.0" style="-fx-border-color: orange;" type="Pane" xmlns="http://javafx.com/javafx/8.0.60">
    <children>
        <Text fx:id="text" layoutX="5.0" layoutY="17.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Text"/>
    </children>
    <clip>
        <Rectangle width="${root.width}" height="${root.height}" />
    </clip>
</fx:root>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM