2017-02-18 24 views

ответ

3

Я исследовал для Lowered-Etched-Border для JavaFX, но я не нашел эффективного документа. Я также тестировал 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 отображает текст на Center-Side только так игнорирует Text-Alignment Properties.

2

Образец на основе расширения Region в сочетании с внешним файлом CSS.

Эта реализация позволяет границе охватить произвольное изменяемое по размеру содержимое (включая родительские макеты), если это необходимо. Например, вы можете разместить StackPane содержимое внутри BorderPane и использовать «Необязательные ограничения компоновки» StackPane для выравнивания содержимого и определения полей для содержимого в пределах BorderPane (см. Связанный Java-код StackPane для примера того, как выполнить это).

Кроме того, стиль самой границы может быть настроен из внешнего файла CSS, поэтому должно быть возможно легко реплицировать любой из standard Swing borders (и других стилей границы).

Testing

границы 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); 
    } 

} 

Связанные Вопрос