我正在尝试将自定义工具栏添加到通用 TitledPane。我的代码似乎可以工作(下面是最小的示例),但我的布局有问题。具体来说:我正在使用 setGraphic() 添加我的工具栏,但这似乎有一个固定的宽度,而我希望它能够扩展,这样我就可以在将标题保持在左侧的同时让按钮向右刷新。
(我无法发布图像,所以我将恢复为 ASCII 艺术)这是以下代码的实际结果:
+------------------------------------+
| > Node 1 [a][b][c][d] |
+------------------------------------+
| > Node |
+------------------------------------+
虽然我想得到类似的东西:
+------------------------------------+
| > Node 1 [a][b][c][d] |
+------------------------------------+
| > Node |
+------------------------------------+
我可以明确地伪造结果设置 BorderPane 宽度,但它不会跟随调整大小!
这里开始代码:
import java.net.URL;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TitledPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Test extends Application {
private Node loadMinitool(String title) {
try {
URL u = getClass().getResource("Minitool.fxml");
FXMLLoader l = new FXMLLoader(u);
Node n = (Node) l.load();
Minitool mtc = (Minitool) l.getController();
mtc.setTitle(title);
return n;
} catch (Exception e) {
System.err.println("Unable to load 'Minitool.fxml': "+e.getMessage());
}
return null;
}
public Parent createContent() {
TitledPane t1 = new TitledPane(null, new Button("Button"));
t1.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
t1.setGraphic(loadMinitool("Node 1"));
TitledPane t2 = new TitledPane("Node 2", new Text("String"));
TitledPane t3 = new TitledPane("Node 3", new Rectangle(120, 50,
Color.RED));
Accordion accordion = new Accordion();
accordion.getPanes().add(t1);
accordion.getPanes().add(t2);
accordion.getPanes().add(t3);
accordion.setMinSize(100, 100);
accordion.setPrefSize(200, 400);
return accordion;
}
@Override
public void start(Stage primaryStage) {
primaryStage.setScene(new Scene(createContent()));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
相关的 FXML 是:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.*?>
<BorderPane maxWidth="1.7976931348623157E308" prefWidth="-1.0" xmlns:fx="http://javafx.com/fxml" fx:controller="com.voith.hyconmde.ui.util.minitool.Minitool">
<left>
<Label fx:id="title" maxWidth="1.7976931348623157E308" text="Title goes here" BorderPane.alignment="CENTER_LEFT" />
</left>
<center>
<Pane fx:id="filler" maxWidth="1.7976931348623157E308" minWidth="0.0" prefHeight="16.0" prefWidth="200.0" />
</center>
<right>
<HBox>
<Button fx:id="add" graphicTextGap="0.0" onAction="#addAction" styleClass="btnToolbar" />
<Button fx:id="del" graphicTextGap="0.0" onAction="#delAction" styleClass="btnToolbar" />
<Button fx:id="sub" graphicTextGap="0.0" onAction="#subAction" styleClass="btnToolbar" />
<Button fx:id="dup" graphicTextGap="0.0" onAction="#dupAction" styleClass="btnToolbar" />
</HBox>
</right>
<stylesheets>
<URL value="@Minitool.css" />
</stylesheets>
</BorderPane>
控制器是:
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class Minitool {
@FXML private ResourceBundle resources;
@FXML private URL location;
@FXML private Button add;
@FXML private Button del;
@FXML private Button dup;
@FXML private Button sub;
@FXML private Label title;
@FXML void addAction(ActionEvent event) {
}
@FXML void delAction(ActionEvent event) {
}
@FXML void dupAction(ActionEvent event) {
}
@FXML void subAction(ActionEvent event) {
}
@FXML void initialize() {
assert add != null : "fx:id=\"add\" was not injected: check your FXML file 'Minitool.fxml'.";
assert del != null : "fx:id=\"del\" was not injected: check your FXML file 'Minitool.fxml'.";
assert dup != null : "fx:id=\"dup\" was not injected: check your FXML file 'Minitool.fxml'.";
assert sub != null : "fx:id=\"sub\" was not injected: check your FXML file 'Minitool.fxml'.";
assert title != null : "fx:id=\"title\" was not injected: check your FXML file 'Minitool.fxml'.";
}
public void setTitle(String title) {
this.title.setText(title);
}
public void setWidth() {
if (parent == null) {
Parent p = minitool.getParent();
if (p != null)
p = p.getParent();
if (p instanceof TitledPane) {
parent = (TitledPane) p;
parent.widthProperty().addListener(new ChangeListener<Object>() {
@Override
public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) {
if (newValue instanceof Number) {
Number n = (Number) newValue;
double d = n.doubleValue();
setFiller(d);
}
}
});
setFiller(parent.getWidth());
}
}
}
protected void setFiller(double d) {
double w = d - title.getWidth() - 180; // XXX: this value has been hand-trimmed!
if (w < 0)
w = 0;
filler.setPrefWidth(w);
}
}