JavaFx:画一个类似摆动的低蚀刻边框可能吗?
JavaFx: drawing a swing-like lowered etched Border possible?
如何在 JavaFX 中绘制类似于在 Swing 标签中看到的内容的 Lower-Etched-Border
?
我研究了 Lowered-Etched-Border
的 JavaFX,但我没有找到任何有效的文档。我还测试了 InnerShadow
和其他效果,但这些效果不太适合。所以我创建了一个LEBLabel
(Label
的子类),类型为border-style。
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);
}
}
Note : This LEBLabel
displays the text on Center-Side only so it ignores the Text-Alignment Properties
.
示例基于 Region 扩展名和外部 CSS 文件。
如果需要,此实现允许边框包含任意可调整大小的内容(包括父布局窗格)。例如,您可以在 BorderPane 内放置一个包含内容的 StackPane 并使用 StackPane 的 "Optional Layout Constraints" 对齐内容并定义 BorderPane 内内容的边距(有关示例,请参见链接的 StackPane javadoc如何实现这一点)。
此外,边框本身的样式可以从外部 CSS 文件自定义,因此应该可以相对容易地复制任何 standard Swing borders(和其他边框样式)。
边框-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);
}
}
相关问题
- GroupBox / TitledBorder in JavaFX 2?
如何在 JavaFX 中绘制类似于在 Swing 标签中看到的内容的 Lower-Etched-Border
?
我研究了 Lowered-Etched-Border
的 JavaFX,但我没有找到任何有效的文档。我还测试了 InnerShadow
和其他效果,但这些效果不太适合。所以我创建了一个LEBLabel
(Label
的子类),类型为border-style。
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);
}
}
Note : This
LEBLabel
displays the text on Center-Side only so it ignores theText-Alignment Properties
.
示例基于 Region 扩展名和外部 CSS 文件。
如果需要,此实现允许边框包含任意可调整大小的内容(包括父布局窗格)。例如,您可以在 BorderPane 内放置一个包含内容的 StackPane 并使用 StackPane 的 "Optional Layout Constraints" 对齐内容并定义 BorderPane 内内容的边距(有关示例,请参见链接的 StackPane javadoc如何实现这一点)。
此外,边框本身的样式可以从外部 CSS 文件自定义,因此应该可以相对容易地复制任何 standard Swing borders(和其他边框样式)。
边框-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);
}
}
相关问题
- GroupBox / TitledBorder in JavaFX 2?