【问题标题】:JavaFx: drawing a swing-like lowered etched Border possible?JavaFx:可以绘制类似秋千的降低蚀刻边框吗?
【发布时间】:2017-07-08 08:57:47
【问题描述】:

如何在 JavaFX 中绘制类似于在 Swing 标签中看到的 Lower-Etched-Border

【问题讨论】:

    标签: java javafx javafx-8 border


    【解决方案1】:

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

    相关问题

    【讨论】:

      【解决方案2】:

      我为 JavaFX 研究了 Lowered-Etched-Border,但我没有找到任何有效的文档。我还测试了InnerShadow 和其他效果,这些效果并不适合。所以我创建了一个带有这种边框样式的LEBLabelLabel 的子类)。

      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

      【讨论】:

        猜你喜欢
        • 2011-08-14
        • 1970-01-01
        • 2015-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多