gpt4 book ai didi

resize - JavaFX 2 TitledPane 图形扩展到全尺寸

转载 作者:行者123 更新时间:2023-12-02 09:24:44 26 4
gpt4 key购买 nike

我正在尝试将自定义工具栏添加到通用 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>

Controller 是:

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);
}
}

最佳答案

您需要做一些基本的数学计算。请对以下代码进行修改:
1)在fxml文件中向HBox添加属性:

<HBox alignment="CENTER_RIGHT" HBox.hgrow="ALWAYS">

结果是,当标题宽度有额外的空间(通过调整大小)时,该 HBox 将优先展开,并且其子项将始终向右(中心)对齐。

2)现在我们需要这样计算剩余的标题宽度

REMAINING_WIDTH = TITLE_TOTAL_WIDTH - TITLE_TEXT_WIDTH - ARROW_BUTTON_WIDTH - RIGHT_LEFT_PADDINGS

计算出的宽度将是我们的工具按钮 Pane (即 HBox)的首选宽度。

public Parent createContent() {

String titleText = "Node 1";

TitledPane t1 = new TitledPane(null, new Button("Button"));
t1.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
t1.setGraphic(loadMinitool(titleText));

double titleTextWidth = computeTextWidth(t1.getFont(), titleText, 0);
double arrowButtonWidth = 14; // I have given a static value here otherwise
// it must be calculated by
// t1.lookup(".arrow-button").getLayoutBounds().getWidth()
// after the primary stage has been shown. Namely after primaryStage.show(); line.
double paddings = 20; // right (10) and left (10) paddings defined in
// caspian.css for title of the pane. These values can also be obtained
// by lookup.
double total = titleTextWidth + arrowButtonWidth + paddings;

HBox toolButtons = (HBox) ((BorderPane) t1.getGraphic()).getRight();
toolButtons.prefWidthProperty().bind(t1.widthProperty().subtract(total));

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;
}

computeTextWidth()代码取自com.sun.javafx.scene.control.skin.Utils ,仅供引用:

private double computeTextWidth(Font font, String text, double wrappingWidth) {
Text helper = new Text();
helper.setText(text);
helper.setFont(font);
// Note that the wrapping width needs to be set to zero before
// getting the text's real preferred width.
helper.setWrappingWidth(0);
double w = Math.min(helper.prefWidth(-1), wrappingWidth);
helper.setWrappingWidth((int) Math.ceil(w));
return Math.ceil(helper.getLayoutBounds().getWidth());
}

您的其他代码保持不变。

关于resize - JavaFX 2 TitledPane 图形扩展到全尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17771190/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com