使用translateX()和translateY()时,窗格布局中的JavaFX文本与其他元素重叠 [英] JavaFX Text inside Pane Layout is overlapping other Elements when using translateX() and translateY()
问题描述
下图是对所发生情况的描述:
The image below is the description of what is happening:
我有 Pane
,其中包含文字
我正在使用下面的代码制作文本
的效果的字幕。因此,当
Pane
没有足够的空间来显示文本时,动画正在启动,文本必须来回传递,以便用户可以完整地看到它。
I have a Pane
which contains a Text
and i am using the code below to make a marquee like effect
of the Text
. So when the Pane
has not enough space to display the text , an animation is starting and the text has to go back and forth so the user can see it whole.
问题是我在使用 setTranslateX()
向左转时期待文本消失,而不是重叠其他元素。例如,这里重叠左边的 StackPane
。
The problem is that i was expecting the text when going to the left using setTranslateX()
to disappear and not overlape the other elements.For example here is overlapping the StackPane
at the left.
代码来自 - > JavaFX Marquee Animation 问题。
The code comes from -> JavaFX Marquee Animation question.
- 为什么会这样?
- 我需要一个解决方案和简要说明:)
以下是代码:
Marquee.java [class]:
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>
推荐答案
为什么这样做那个?
Why does it do that?
默认情况下,JavaFX也会在节点边界之外绘制子节点。
JavaFX by default also draws children outside of a nodes bounds.
如何修复?
使用剪辑
父级的属性,用于在 Pane
的范围内剪辑内容:
Use the clip
property of the parent to clip the content at the bounds of the 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>
这篇关于使用translateX()和translateY()时,窗格布局中的JavaFX文本与其他元素重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!