我希望在StackPane中对齐Rectangle
和Label
,但是我的代码无法达到预期效果:
FXML:
<fx:root type="HBox" xmlns:fx="http://javafx.com/fxml">
<StackPane fx:id="pane">
<children>
<Rectangle fx:id="bubble" fill="#ffffff"></Rectangle>
<Label fx:id="message" style="-fx-border-color:black; -fx-border-width: 1; -fx-border-style: solid;"></Label>
</children>
</StackPane>
</fx:root>
控制器:
public class MessageBubble extends HBox implements Initializable {
@FXML
private StackPane pane;
@FXML
private Label message;
@FXML
private Rectangle bubble;
@Override
public void initialize(URL location, ResourceBundle resources) {
message.setText("message");
pane.setAlignment(Pos.CENTER);
bubble.setArcWidth(15.0);
bubble.setArcHeight(15.0);
bubble.setStroke(Color.BLACK);
message.widthProperty().add(10.0).addListener((observable, oldValue, newValue) -> {
bubble.setWidth(newValue.doubleValue());
pane.layout();
});
message.heightProperty().add(10.0).addListener((observable, oldValue, newValue) -> {
bubble.setHeight(newValue.doubleValue());
pane.layout();
});
}
public MessageBubble() {
FXMLLoader loader = new FXMLLoader(this.getClass().getResource("MessageBubble.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
}
更新
如果我以编程方式进行大小调整,它会很好地对齐:
this.pane.getChildren().addAll(this.bubble, this.message);
bubble.setFill(Color.ALICEBLUE);
bubble.setArcWidth(15.0);
bubble.setArcHeight(15.0);
bubble.setStroke(Color.BLACK);
message.setStyle("-fx-border-color:black; -fx-border-width: 1; -fx-border-style: solid;");
message.setText("message");
message.setPrefWidth(60.0);
message.setPrefHeight(25.0);
bubble.setWidth(70.0);
bubble.setHeight(30.0);
但是这样,我需要自己计算尺寸。
答案 0 :(得分:1)
基本上,如果您需要带有彩色背景的Text
或Label
,则最简单的方法是将CSS用于单个Label
或Text
,而不使用任何{{1}对象。
使用带CSS的标签的示例
Main.java
Rectangle
application.css
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
HBox root = new HBox();
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
Label message = new Label();
TextArea textArea = new TextArea();
textArea.setPrefWidth(200);
textArea.setText("message");
message.textProperty().bind(textArea.textProperty());
message.getStyleClass().add("rounded-background-label");
root.getChildren().addAll(message, textArea);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
@jewelsea对这个问题的回答非常详细:
JavaFX 2: resizable rectangle containing text
但是如果你想继续使用Label + Rectangle解决方案
我担心这与此错误有关:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8137252
作为解决方法,您可以像在侦听器中尝试的那样请求.rounded-background-label {
-fx-background-color: black, white;
-fx-background-insets: 0, 1;
-fx-padding: 10px;
-fx-background-radius: 12px;
}
的布局更新。
您的代码唯一的问题是您应该替换:
StackPane
与
pane.layout();
将确保布局将在GUI线程上发生。
示例强>
LabelRectangleTest.fxml
Platform.runLater(new Runnable() {
@Override
public void run() {
pane.requestLayout();
}
});
LabelRectangleTestController.java
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.*?>
<HBox prefHeight="100.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="application.LabelRectangleTestController">
<children>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<StackPane fx:id="pane" minHeight="126.0" prefHeight="126.0" prefWidth="200.0" HBox.hgrow="ALWAYS">
<children>
<Rectangle fx:id="bubble" arcHeight="15.0" arcWidth="15.0" fill="WHITE" height="27.75" stroke="BLACK" strokeType="INSIDE" width="68.0" />
<Label fx:id="message" text="Label" />
</children>
</StackPane>
<TextArea fx:id="textArea" prefWidth="200.0" wrapText="true" />
</children>
</HBox>
</children>
</HBox>
Main.java
public class LabelRectangleTestController implements Initializable {
@FXML
private Label message;
@FXML
private Rectangle bubble;
@FXML
private StackPane pane;
@FXML
private TextArea textArea;
@Override
public void initialize(URL location, ResourceBundle resources) {
textArea.setText("message");
message.textProperty().bind(textArea.textProperty());
message.widthProperty().addListener((observable, oldValue, newValue) -> {
bubble.setWidth(newValue.intValue() + 10);
Platform.runLater(new Runnable() {
@Override
public void run() {
pane.requestLayout();
}
});
});
message.heightProperty().addListener((observable, oldValue, newValue) -> {
bubble.setHeight(newValue.doubleValue() + 10);
Platform.runLater(new Runnable() {
@Override
public void run() {
pane.requestLayout();
}
});
});
}
}