如何摆脱JavaFX中拆分窗格周围的边框?

时间:2013-05-31 11:34:45

标签: javafx-2 scenebuilder

我正在使用JavaFX SceneBuilder,但我会在下面粘贴FXML,因为它很短。我有一个非常简单的窗口,在窗格内有一个分割窗格。这是FXML:

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

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <SplitPane id="main-split-pane" dividerPositions="0.25" focusTraversable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="-1.0" prefWidth="-1.0" style="" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <items>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" style="" />
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
      </items>
    </SplitPane>
  </children>
  <padding>
    <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
  </padding>
  <stylesheets>
    <URL value="@main-view.css" />
  </stylesheets>
</AnchorPane>

我正在使用以下CSS:

#main-split-pane {
    -fx-border-style: none;
    -fx-border-color: blue;
    -fx-border-width: 25;
}

它给了我这样一个窗口:

我玩过here显示的CSS设置,但有一些事情我无法理解:

  1. 我用红色箭头标出的边框在哪里?
  2. 为什么将-fx-border-style设置为none会导致-fx-border-color被忽略,而-fx-border-width仍然会对事物的外观产生影响(如填充)?

2 个答案:

答案 0 :(得分:37)

解决方案 - 如何从拆分窗格中删除边框

如果您不想显示边框,请覆盖-fx-box-border颜色定义:

split.setStyle("-fx-box-border: transparent;");

拆除边框的拆分窗格

bananasplit

示例代码

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class SplitPaneBorderRemover extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(final Stage stage) throws Exception {
    StackPane r1 = new StackPane();
    r1.setPrefSize(200, 150);
    r1.setStyle("-fx-background-color: palegreen;");

    StackPane r2 = new StackPane();
    r2.setPrefSize(200, 150);
    r2.setStyle("-fx-background-color: coral;");

    SplitPane split = new SplitPane();
    split.getItems().setAll(
      r1, r2
    );
    split.setStyle("-fx-box-border: transparent;");

    StackPane layout = new StackPane();
    layout.getChildren().setAll(split);
    layout.setStyle("-fx-padding: 20px; -fx-background-color: cornsilk");

    stage.setScene(new Scene(layout));
    stage.show();
  }
}

其他问题的答案

  

我用红色箭头标出的边框在哪里?

它是默认css样式表(caspian.css for JavaFX 2.2modena.css for Java 8))中的背景样式。

  

为什么将-fx-border-style设置为none会导致忽略-fx-border-color,而-fx-border-width仍然会对事物的外观产生影响(如填充)?

因为使用背景定义而不是边框​​定义显示拆分窗格的边框。所有默认的JavaFX控件css样式都以这种方式工作。他们设置了多个重叠背景来完成边框技术,而不是通过设置显式边框属性。

了解答案的工作原理

虽然这个答案实际上只是一个简单的单线,但我会花一些时间来解释它为何有效。对不起,如果这个解释膨胀了答案。那些已经知道这些信息的人可以忽略这部分答案。

  

我仍然无法理解这个概念

花一些时间阅读JavaFX css reference guide,我知道有点干,但如果你想了解JavaFX css样式,那么必读。

还有一个official Oracle tutorial for css,但它不会像阅读css参考和研究我之前链接的默认样式表一样教你。

我从css参考中提取了相关的语句,并在这里引用它们:

  

JavaFX具有丰富的CSS扩展集,支持颜色派生,属性查找以及单个节点的多种背景颜色和边框等功能。这些功能为开发人员和设计人员增添了重要的新功能,本文档对此进行了详细介绍。

设置为透明以删除边框的-fx-box-border根本不是边框,它是一种已经应用于分割窗格的多个背景之一的查找颜色。 / p>

  

使用查找颜色,您可以引用当前节点或其任何父节点上设置的任何其他颜色属性。这是一个非常强大的功能,因为它允许在场景中指定颜色的通用调色板,然后在整个应用程序中使用。如果要更改其中一种调色板颜色,可以在场景树中的任何级别执行此操作,它将影响该节点及其所有后代。查找颜色在应用之前不会被查找,因此它们是实时的并且可以对可能发生的任何样式更改做出反应,例如在运行时使用&#34;样式替换调色板颜色&#34;节点上的属性。

     

在以下示例中,所有按钮的所有背景颜色都使用了查找的颜色&#34; abc&#34;。

     

.root { abc: #f00 }

     

.button { -fx-background-color: abc }

Java 8 modena.css样式的-fx-box-border的默认定义是:

/* A little darker than -fx-color and used to draw boxes around objects such
 * as progress bars, scroll bars, scroll panes, trees, tables, and lists.
 */
-fx-box-border: ladder(
    -fx-color,
    black 20%,
    derive(-fx-color,-15%) 30%
);

分割窗格的默认样式是&#34; Box Like Thing&#34;:

/* ====   BOX LIKE THINGS   ================================================= */

.scroll-pane,
.split-pane,
.list-view,
.tree-view,
.table-view, 
.tree-table-view,
.html-editor {
    -fx-background-color: -fx-box-border, -fx-control-inner-background;
    -fx-background-insets: 0, 1;
    -fx-padding: 1;
}
. . .
/* ones with grey -fx-background not lighter -fx-control-inner-background */
.scroll-pane,
.split-pane {
    -fx-background-color: -fx-box-border, -fx-background;
}

因此,分析css,您可以看到,对于未聚焦的分割窗格,定义了两个背景(作为.split-pane的最新或最具体的-fx-background-color定义获胜css&#39;奇怪的申请规则)。内部背景颜色为-fx-background并且插入一个像素。外部背景颜色为-fx-box-border而不是插入。拆分窗格的填充设置为一个像素。这可以防止拆分窗格内容覆盖其周围的一个像素边框。

本答案中的解决方案是通过使用setStyle方法覆盖特定于给定splitpane实例的代码中的查找颜色定义。通过将-fx-box-border设置为透明(尽管也许null也可以同样使用并且可能更高效),边框设置为不可见(即使它仍然存在并且它的填充仍然存在在1像素的CSS)。

进一步修改css(通过应用您自己的用户样式表来覆盖默认的分割窗格样式类)可以根据需要删除这一个像素填充:

.split-pane {
    -fx-background-color: -fx-control-inner-background;
    -fx-background-insets: 0;
    -fx-padding: 0;
}

现在所有边框的痕迹都消失了,您的内容可以自由填充分割窗格的整个区域,包括以前是边框的1个像素区域。我更喜欢将-fx-box-border设置为透明的最小变化,因为那时您的用户样式定义很小,并且不会从默认样式中详细说明。

  

例如,set -fx-box-border:red;并且您将在拆分窗格周围获得1px红色边框。

是的,因为-fx-box-border颜色着色的默认背景区域只有1像素宽,您只需将像素颜色明确设置为红色。

  

我认为它是填充组件上的盒子边框。

不,如上所述,原因是因为背景-fx-box-border是距离区域边缘0像素的插入而内部背景-fx-background-color是从边缘插入1像素区域,使用-fx-box-border保留1个像素宽度。在这种情况下,所有-fx-padding都在确保拆分窗格内容不会在拆分窗格的1像素外部背景上绘制。

  

然后设置-fx-padding:5;在分裂。红色框边框消失,另一个灰色边框出现。

&#34;灰色边框&#34;总是在那里 - 它是分裂窗格css样式(-fx-background one)中定义的第二个内部背景。默认的-fx-background颜色为灰色。通过将-fx-padding设置为5,您可以将拆分窗格的内容从splitpane区域的外边缘插入5个像素。这允许显示默认背景。

如果您的内容有一些透明区域并且没有填充分割窗格的整个可用区域,那么您还会在这些透明区域中看到这种灰色-fx-背景色的颜色。

如果您想要的是在-fx-box-border颜色的内容周围实现5像素边框,那么您需要调整填充和边框插入,例如:

.split-pane {
    -fx-background-color: -fx-box-border, -fx-control-inner-background;
    -fx-background-insets: 0, 5;
    -fx-padding: 5;
}

如果对大型应用程序的填充,背景插入,css样式派生规则等的手动分析似乎令人生畏,请知道有工具支持来帮助理解场景图结构和css应用程序。要使用的工具是SceneBuilder's css analyzer用于设计时css分析,ScenicView用于运行时场景图和css分析。

答案 1 :(得分:0)

如果要删除拆分窗格周围的边框,但保留分隔线,请执行以下操作:

.split-pane {
  -fx-background-color: transparent, -fx-background;
}