2016-12-16 1 views
0

나는 Pane을 포함하는 VBox입니다. VBox에서 나는 다른 요소를 보여주고 싶습니다 (현재는 Pane입니다). 이 요소는 VBox에 복수 Pane을 오버레이해야하므로이 요소를 AnchorPane 안에 VBox과 함께 넣습니다. 전체 구조는 다음과 같습니다JavaFX 자동 크기 조정 및 자동 위치 지정

HBox 
    VBox 
    Label <--- "Friday" 
    AnchorPane 
     VBox <--- the VBox with Panes 
     Pane 
     ... 
     Pane <--- the Pane over the VBox (red in images) 

문제는 내가 창 크기를 조정할 때, 빨간색 Pane 크기를 조정하거나 위치를 변경하지 않습니다.

보통 크기 :

normal

작은 크기 : small

나는 빨간 Pane이 (3) 같은 줄에서 시작하여되기를 원한다면 동일 상대 크기.

PaneprefWidthPropertyprefHeightProperty을 부모 (AnchorPane)와 바인딩하려고했습니다. 이것은 자동 크기 조정을 위해 작동합니다.

자동 위치 지정의 경우 시스템에서 설정 한 layoutX|Y 속성을 바인드하려고했는데이 속성은 시스템에서 설정하고 "바운드 값을 설정할 수 없습니다"라는 예외가 발생합니다. 그래서 Pane을 비 관리로 만들려고했는데, 관리되지 않는 노드에서는 기본 설정의 변경 사항이 적용되지 않으므로 자동 크기 조정이 중단되었습니다. 부모 속성에 widthPropertyheightProperty을 바인딩하는 것을 생각했지만 읽기 전용입니다.

+0

을 바인딩을 사용하여 상황을 동기화 상태로 유지합니다. – Mordechai

+0

어떤 바인딩이 필요합니까? 어디에서 설정합니까? – kyrill

+0

내가 입력 할 때 편집을 보지 못했습니다. 내 대답을 보라. – Mordechai

답변

3

이와 같은 기능을 위해 GridPane을 사용해보십시오. 그리드의 동일한 셀에 여러 개의 노드를 추가 할 수 있습니다 (마지막에 추가 된 셀은 z 순서로 맨 위에 나타납니다). GridPane은 레이아웃 유연성을 최대화합니다. 여기에 예제가 있습니다 : 여기에는 많은 스타일이 있습니다. 간결하게하기 위해 하드 코딩했는데, 실제 앱에서는 이것을 외부 스타일 시트로 옮겨야합니다 (최대 크기 등으로 동일하게 할 수 있습니다) :

import java.time.DayOfWeek; 
import java.time.Duration; 
import java.time.LocalTime; 
import java.time.format.DateTimeFormatter; 

import javafx.application.Application; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.layout.ColumnConstraints; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.Region; 
import javafx.scene.layout.RowConstraints; 
import javafx.stage.Stage; 

public class CalendarExample extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     GridPane calendar = new GridPane(); 

     // headers: 
     for (DayOfWeek dayOfWeek = DayOfWeek.MONDAY ; dayOfWeek.getValue() <= DayOfWeek.FRIDAY.getValue(); 
       dayOfWeek = DayOfWeek.of(dayOfWeek.getValue() + 1)) { 

      Label label = new Label(dayOfWeek.toString()); 
      label.setAlignment(Pos.CENTER); 
      label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); 
      label.setStyle("-fx-background-color: black, darkgray; -fx-background-insets: 0, 0 0 1 1 ;"); 
      calendar.add(label, dayOfWeek.getValue(), 0); 
     } 

     DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm"); 

     int rowCount = 0 ; 

     for (LocalTime time = LocalTime.of(8, 0); time.isBefore(LocalTime.of(17, 0)); time=time.plusMinutes(30)) { 
      rowCount++ ; 
      Label label = new Label(timeFormatter.format(time)); 
      label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); 
      label.setAlignment(Pos.CENTER); 
      String color = rowCount % 2 == 0 ? "darkgray" : "lightgray" ; 
      label.setStyle("-fx-background-color: black, "+color+"; -fx-background-insets: 0, 0 0 1 1;");   
      calendar.add(label, 0, rowCount); 
     } 

     // cells: 

     for (int x = 1 ; x <= 5; x++) { 
      for (int y = 1 ; y <= rowCount; y++) { 
       Region region = new Region(); 
       String color = y % 2 == 0 ? "darkgray" : "lightgray" ; 
       region.setStyle("-fx-background-color: black, "+color+"; -fx-background-insets: 0, 0 0 1 1 ;"); 
       calendar.add(region, x, y); 
      } 
     } 

     // Column constraints: 
     for (int x = 0 ; x <= 5 ; x++) { 
      ColumnConstraints cc = new ColumnConstraints(); 
      cc.setPercentWidth(100.0/6); 
      cc.setFillWidth(true); 
      calendar.getColumnConstraints().add(cc); 
     } 

     // row constraints: 
     for (int y = 0 ; y <= rowCount; y++) { 
      RowConstraints rc = new RowConstraints(); 
      rc.setPercentHeight(100.0/(rowCount+1)); 
      rc.setFillHeight(true); 
      calendar.getRowConstraints().add(rc); 
     } 

     // Example appointment block: 

     DayOfWeek appointmentDay = DayOfWeek.FRIDAY ; 
     LocalTime startTime = LocalTime.of(10, 0); 
     LocalTime endTime = LocalTime.of(13, 0); 

     String appointmentText = "Fridays need really long coffee breaks"; 
     Label appointment = new Label(appointmentText); 
     appointment.setTooltip(new Tooltip(appointmentText)); 
     appointment.setWrapText(true); 
     appointment.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); 

     appointment.setStyle("-fx-background: red; -fx-background-color: -fx-background; "); 
     GridPane.setMargin(appointment, new Insets(2, 5, 2, 2)); 


     Scene scene = new Scene(calendar, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

enter image description here

이 또한 창 크기를 조정할 때 필요에 따라 동작 :

enter image description here

+0

고마워, 그게 내가 필요한거야! 다른 질문으로는 첫 번째 열의 열 (":")에서 시간을 정당화 할 수 있습니까? – kyrill

+0

@kyrill 나는 쉬운 방법을 생각할 수 없다. 마음에 떠오르는 한가지 생각은 그 행의 각 셀에서 하나의 행과 3 개의 열을 갖는'GridPane'을 사용하는 것입니다. 열 제한을 사용하여 처음과 마지막 열의'hgrow'를'ALWAYS'로 설정하고 중간 열을'NEVER'로 설정하십시오; 첫 번째 컬럼에 대해 'halignment'를 'RIGHT'로 설정하고 세 번째 컬럼에 대해서는 'LEFT'로 설정하십시오. 그런 다음 각 셀에 레이블을 넣으십시오 : 시간,'': "', 분. 그렇게 할 수는 있지만 다소 복잡합니다. –

+0

@kyrill 또한 문제가 해결되면 대답을 올바르게 표시하십시오. 다른 사용자가 쉽게 찾을 수 있습니다. (나는 당신이 어떤 대답도 아직 정확한 것으로 표시하지 않았다는 것을 알아 차린다.). –

0

빨간색 사각형 만 있으면 창 대신 Rectangle 모양을 사용하는 것이 좋습니다. 이렇게하면 너비와 높이를 명시 적으로 바인딩 할 수 있습니다.

+0

실제로'Pane'에는 텍스트 ('Label' 또는 뭔가)가 포함될 것이기 때문에 저는'Rectangle'을 사용할 수 있을지 잘 모르겠습니다. 부모에게 청취자를 사용하여 해결했습니다. 어쨌든 고마워. – kyrill

+0

@kyrill 리스너를 사용하여 레이아웃을 관리하는 경우 거의 확실한 방법이 있습니다. 이 작업을 수행하는 일종의 레이아웃 패널을 사용하십시오. –

+0

어떤 종류입니까? JavaFX를 처음 접했을 때 도움이되었습니다. 감사. – kyrill

1

widthheight 속성은 읽기 전용이 될 수 있지만, 당신은 할 수 선호하는 크기를 할당하고 autosize을 사용하십시오.

다음 코드는 오버레이 50 % 높이에서 시작하고 VBox 높이의 1/3의 높이가 있습니다 : 당신은 오프셋 요구의 논리를 구현할 수

@Override 
public void start(Stage primaryStage) { 
    Region region1 = new Region(); 
    VBox.setVgrow(region1, Priority.ALWAYS); 
    region1.setStyle("-fx-background-color: blue;"); 

    Region region2 = new Region(); 
    VBox.setVgrow(region2, Priority.ALWAYS); 
    region2.setStyle("-fx-background-color: lime;"); 

    Region regionOverlay = new Region(); 
    regionOverlay.setStyle("-fx-background-color: red;"); 
    regionOverlay.setManaged(false); 

    VBox root = new VBox(region1, region2, regionOverlay); 
    root.layoutBoundsProperty().addListener((observable, oldValue, newValue) -> { 
     regionOverlay.setPrefSize(newValue.getWidth() - 20, newValue.getHeight()/3); 
     regionOverlay.setLayoutX(10); 
     regionOverlay.setLayoutY(newValue.getHeight()/2); 
     regionOverlay.autosize(); 
    }); 

    root.setPrefSize(400, 400); 

    Scene scene = new Scene(root); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
}