JavaFX:如何制作合适的垂直工具栏?

标签 javafx toolbar

我想制作一个垂直工具栏,按钮垂直排列。在 Linux Mint 中使用 JDK 7 中包含的 JavaFX 2.2

截图显示了问题:

enter image description here

我使用的 FXML 如下所示:

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

<?language javascript?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane prefHeight="800.0" prefWidth="700.0" styleClass="root" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <top>
        <ToolBar>
            <items>
                <Button text="Test" />
            </items>
        </ToolBar>

    </top>
    <left>
        <ToolBar orientation="VERTICAL" style="-fx-background-color: blue;">
            <items>

                        <Region style="-fx-padding:10;" />
                        <Button rotate="-90" text="Project" style="-fx-label-padding:1;"/>
                        <Region style="-fx-padding:10;" />
                        <Button rotate="-90" text="Structure" />

            </items>
        </ToolBar>
    </left>
    <center>
        <HBox>
            <children>
            </children>
        </HBox>
    </center>
    <bottom>
        <ToolBar prefHeight="18.0" prefWidth="472.0">
            <items>
                <Region styleClass="spacer" />
                <HBox>
                    <children>

                    </children>
                </HBox>
            </items>
        </ToolBar>
    </bottom>

</BorderPane>

我的定义中正确的工具栏是:按钮放置正确并且工具栏与按钮的宽度一样宽。蓝色表示工具栏当前的宽度。

最佳答案

将旋转的工具项包装在一个组中,然后工具栏的内置布局将知道旋转是永久性的,应在布局计算中考虑到,而不仅仅是可能用于动画的临时事物。阅读 Group 的 javadoc ,其中讨论了布局边界计算以更好地理解这一点。

tools

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

<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>


<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: cornsilk;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <ToolBar orientation="VERTICAL" style="-fx-base: palegreen;">
        <items>
            <Group>
               <children>
                <Button rotate="-90.0" style="-fx-base: gold;" text="Project" />
               </children>
            </Group>
            <Group>
               <children>
                  <Button rotate="-90.0" style="-fx-base: khaki;" text="Structure" />
               </children>
            </Group>
        </items>
      </ToolBar>
   </children>
</HBox>

2017 年 4 月 24 日更新

上述解决方案就其本身而言是很好的,但确实存在一个问题,即工具栏中的按钮在获得焦点时未对齐。

群组的作用是根据其内容调整自身规模。当内容的大小发生变化时,组的大小也会发生变化。当按钮或控件在 JavaFX 中获得焦点时,它会获得 focus ring围绕控制。对焦环的显示是在 CSS 中定义的,并且包含用于背景插入显示的负值。结果是,当控件获得焦点时,它会比未获得焦点时稍大。通常,当您使用标准布局 Pane 时,这不是问题,因为出于布局目的,布局 Pane 将忽略背景插图。然而,一个团队会考虑整个尺寸,并且不会忽略对焦环。结果是,仅包含一个控件的组在聚焦或未聚焦时其大小会略有变化。这给上述解决方案带来了一个问题,因为当按钮获得焦点时,它会稍微变大,并且工具栏中的布局也会发生变化,这并不理想。

上述代码中焦点转移问题的解决方案是仅旋转组内的整个工具栏,而不是旋转每个按钮组内的每个按钮。这工作正常,但随后出现了一些其他问题,例如工具栏没有占据场景左侧的整个可用区域(由于将其包装在一个组中,从而删除了工具栏的动态布局属性)。为了解决这个问题,可以使用代码中的绑定(bind)将工具栏的大小调整到其父布局容器的可用区域。

所以我们最终得到了下面稍微详细一点的解决方案:

focusedtooldisplay

skinsample/toolbar.fxml

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

<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.Group?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>

<?import javafx.scene.control.ToggleGroup?>
<BorderPane fx:id="border" prefHeight="200.0" prefWidth="100.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="skinsample.VerticalToolbarController">
   <left>
     <Group>
       <fx:define>
         <ToggleGroup fx:id="selectedTool"/>
       </fx:define>
       <ToolBar fx:id="toolbar" rotate="-90.0" style="-fx-base: palegreen;">
         <Pane HBox.hgrow="ALWAYS" />
         <ToggleButton style="-fx-base: khaki;" text="Structure" toggleGroup="${selectedTool}"/>
         <ToggleButton style="-fx-base: gold;" text="Project" toggleGroup="${selectedTool}" selected="true"/>
       </ToolBar>
     </Group>
   </left>
</BorderPane>

skinsample/VerticalToolbarController.java

package skinsample;

import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;

public class VerticalToolbarController {

    @FXML
    private BorderPane border;

    @FXML
    private ToolBar toolbar;

    public void initialize() {
        toolbar.minWidthProperty().bind(Bindings.max(border.heightProperty(), toolbar.prefWidthProperty()));
    }
}

skinsample/ToolDisplayApp.java

package skinsample;

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

public class ToolDisplayApp extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("toolbar.fxml"));
        Scene scene = new Scene(loader.load());
        stage.setScene(scene);
        stage.show();
    }

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

}

注释:

  1. 此解决方案还演示了如何使用 ToggleButtons 而不是工具栏中的标准按钮。
  2. 我们还消除了工具栏的默认溢出行为(因为在垂直工具栏的情况下似乎有点烦人),使用:

    toolbar.minWidthProperty().bind(Bindings.max(border.heightProperty(), toolbar.prefWidthProperty()));
    
  3. 如果您想保留溢出行为,请使用:

    toolbar.prefWidthProperty().bind(border.heightProperty());
    
<小时/>

焦点问题的替代解决方案(使用 CSS 完全删除焦点环),如下所示:

关于JavaFX:如何制作合适的垂直工具栏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24774112/

相关文章:

新窗口中的 JavaFX 进度指示器不会 "spin"

JavaFx ListView CellLayout 缩放

Android : I have a toolbar with a sliding tab . 现在,当用户更改选项卡时,我如何更改工具栏上的数据

c# - 在已经添加项目后,如何向 UIToolbar 添加/删除 UIBarButtonItem?

multithreading - java.lang.IllegalStateException : Not on FX application thread Calling Function

css - 如何在 CSS 中设置 JavaFX 菜单及其元素的样式?

java - 如何在JavaFx中移动工具栏中的图像

android - 如何将AppBarLayout的高度设置为0

java - 计算 FilteredList 中项目(元素)的平均值

java - 用 JLayer 装饰滚动工具栏按钮绘制其边框