【发布时间】:2017-07-08 08:57:47
【问题描述】:
如何在 JavaFX 中绘制类似于在 Swing 标签中看到的 Lower-Etched-Border?
【问题讨论】:
标签: java javafx javafx-8 border
如何在 JavaFX 中绘制类似于在 Swing 标签中看到的 Lower-Etched-Border?
【问题讨论】:
标签: java javafx javafx-8 border
基于 Region 扩展名和外部 CSS 文件的示例。
如果需要,此实现允许边框包含任意可调整大小的内容(包括父布局窗格)。例如,您可以在 BorderPane 中放置一个包含内容的 StackPane,并使用 StackPane 的“可选布局约束”来对齐内容并为 BorderPane 中的内容定义边距(请参阅链接的 StackPane javadoc,了解如何来实现这一点)。
此外,边框本身的样式可以从外部 CSS 文件中自定义,因此应该可以相对轻松地复制任何 standard Swing borders(和其他边框样式)。
border-pane.css
.border-pane {
-fx-border-base: gray;
-fx-border-shadow: white;
-fx-light-border: derive(-fx-border-base, 25%);
-fx-border-color: -fx-light-border -fx-border-base -fx-border-base -fx-light-border;
-fx-border-insets: 0 1 1 0;
-fx-background-color: -fx-border-shadow, -fx-background;
-fx-background-insets: 1 0 0 1, 2;
-fx-padding: 2;
}
LoweredEtchedBorderLabelBackgroundDemo.java
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class LoweredEtchedBorderDemo extends Application {
@Override
public void start(Stage stage) {
Label label = new Label("Testing");
label.setPadding(new Insets(10));
// uncomment to see the area that the content node is taking up within the border.
//label.setStyle("-fx-background-color: palegreen;");
BorderPane borderPane = new BorderPane(new StackPane(label));
// uncomment these two lines if you would like the border to resize to fit available space.
borderPane.setMinSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
borderPane.setMaxSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
VBox layout = new VBox(borderPane);
layout.setPadding(new Insets( 10));
layout.setStyle("-fx-base: lightgrey;");
VBox.setVgrow(borderPane, Priority.ALWAYS);
Scene scene = new Scene(layout);
stage.setScene(scene);
stage.show();
}
private class BorderPane extends Region {
// clip the bordered content within the bordered area.
Rectangle clipRect = new Rectangle(getWidth(), getHeight());
public BorderPane(Node content) {
super();
getChildren().add(content);
getStylesheets().add(getClass().getResource(
"border-pane.css"
).toExternalForm());
getStyleClass().add("border-pane");
// by default size the border to the preferred size of the content.
setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
content.setClip(clipRect);
}
@Override protected void layoutChildren() {
final double width = getWidth();
double height = getHeight();
double top = getInsets().getTop();
double right = getInsets().getRight();
double left = getInsets().getLeft();
double bottom = getInsets().getBottom();
double contentWidth = width - left - right;
double contentHeight = height - top - bottom;
Node child = getManagedChildren().get(0);
layoutInArea(child, left, top,
contentWidth, contentHeight,
0, null,
HPos.LEFT,
VPos.TOP);
clipRect.setWidth(contentWidth);
clipRect.setHeight(contentHeight);
}
}
public static void main(String[] args) {
launch(args);
}
}
相关问题
【讨论】:
我为 JavaFX 研究了 Lowered-Etched-Border,但我没有找到任何有效的文档。我还测试了InnerShadow 和其他效果,这些效果并不适合。所以我创建了一个带有这种边框样式的LEBLabel(Label 的子类)。
public class LoweredEtchedBorderLabelDemo extends Application {
@Override
public void start(Stage primaryStage) {
LEBLabel text = new LEBLabel("Testing", 200, 30);
StackPane root = new StackPane();
root.getChildren().add(text);
root.setStyle("-fx-background-color:lightgrey");
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Lowered-Etched-Border Demo");
primaryStage.setScene(scene);
primaryStage.show();
}
//Lowered Etched Borderd Label
private class LEBLabel extends Label {
private HBox[] borders = new HBox[3];
private String border_styles[] = {"-fx-border-width:0 1 1 0; -fx-border-color: white",
"-fx-border-width:1; -fx-border-color:grey",
"-fx-border-width:1 0 0 1; -fx-border-color:white"};
public LEBLabel(String text, double width, double height) {
super(text);
for(int i = 0; i < borders.length; i++) {
borders[i] = new HBox();
borders[i].setStyle(border_styles[i]);
//decrement of border-size for inner-border, prevents from the overlapping of border
borders[i].setMaxSize(width - (1.5 *i), height - (1.5 * i));
borders[i].setMinSize(width - (1.5 *i), height - (1.5 * i));
borders[i].setSpacing(0);
}
this.setContentDisplay(ContentDisplay.CENTER);
this.borders[1].getChildren().add(borders[2]);
this.borders[0].getChildren().add(borders[1]);
this.setGraphic(borders[0]);
}
}
public static void main(String[] args) {
launch(args);
}
}
注意:此
LEBLabel仅在中心侧显示文本,因此它忽略了Text-Alignment Properties。
【讨论】: