2013-03-18 60 views
3

我有一個JavaFX 2 GUI,其中包含一個HBox填充GridPane的一個單元格。我所有的組件都是動態調整大小的。這顯示很好,沒有問題。剪輯GridPane中的HBox

第一個問題:我想將HBox的內容剪輯在GridPane單元格的邊緣,這樣就不會顯示任何溢出,但我無法弄清楚。我嘗試將我的HBox的剪輯設置爲相同尺寸的矩形,但這不起作用。我想是因爲它使用了用於佈局的尺寸,而不是顯示的尺寸。我是否應該修剪GridPane本身,或者至少使用它的屬性?

第二個問題(對於獎勵積分):剪輯如何與翻譯和縮放Node進行交互?

感謝您的任何幫助。

+0

請詢問您的第二個問題作爲一個單獨的問題 – jewelsea 2013-03-18 21:05:12

回答

3

我嘗試了幾個簡短的程序,嘗試在GridPane中剪切節點。 沒有任何剪輯嘗試的實現我真的很喜歡這一切,儘管其中大多數都以某種方式工作,這取決於需求。

最接近您的描述的剪輯嘗試是最後一個將剪裁節點包裹在具有其自身尺寸說明符的區域中,以便剪切區域的佈局與應用於該節點的剪輯節點的大小相匹配。

class ClippedNode extends Region { 
    private final Node content; 
    private final double width; 
    private final double height; 

    ClippedNode(Node content, double width, double height) { 
    this.content = content; 
    this.width = width; 
    this.height = height; 

    content.setClip(new Rectangle(width, height)); 

    getChildren().setAll(content); 
    } 

    @Override protected double computeMinWidth(double d) { return width; } 
    @Override protected double computeMinHeight(double d) { return height; } 
    @Override protected double computePrefWidth(double d) { return width; } 
    @Override protected double computePrefHeight(double d) { return height; } 
    @Override protected double computeMaxWidth(double d) { return width; } 
    @Override protected double computeMaxHeight(double d) { return height; } 
} 

clippednode sample

一個完整的可執行樣品展示的各種片段的方法提供如下:

import java.util.Iterator; 
import javafx.application.Application; 
import javafx.beans.value.*; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.scene.shape.Rectangle; 
import javafx.scene.text.Text; 
import javafx.stage.Stage; 

public class GridClipping extends Application { 
    String buttonText[] = "The quick brown fox jumped over the lazy dog".split(" "); 
    String[] colors = { "aqua", "coral", "cornsilk", "cornflowerblue" }; 

    @Override public void start(Stage stage) throws Exception { 
    final GridPane grid = new GridPane(); 
    grid.addRow(0, createHBox("aqua"),  createHBox("coral")); 
    grid.addRow(1, createHBox("cornsilk"), createHBox("cornflowerblue")); 
    grid.setStyle("-fx-border-color: red;"); 

    final GridPane gridWithClippedBoxes = new GridPane(); 
    gridWithClippedBoxes.addRow(0, createClipWrappedHBox("aqua"),  createClipWrappedHBox("coral")); 
    gridWithClippedBoxes.addRow(1, createClipWrappedHBox("cornsilk"), createClipWrappedHBox("cornflowerblue")); 
    gridWithClippedBoxes.setStyle("-fx-border-color: red;"); 

    final RadioButton noClip   = new RadioButton("No Clip"); 
    final RadioButton restrictGridSize = new RadioButton("Restrict Max Grid Size (doesn't work)"); 
    final RadioButton clipGrid   = new RadioButton("Clip Grid"); 
    final RadioButton clipHBoxes  = new RadioButton("Clip HBoxes"); 
    final RadioButton clipWrappedHBoxes = new RadioButton("Clip Wrapped HBoxes"); 

    final ToggleGroup clipRadios  = new ToggleGroup(); 
    clipRadios.getToggles().setAll(
    noClip, 
    restrictGridSize, 
    clipGrid, 
    clipHBoxes, 
    clipWrappedHBoxes 
    ); 

    final Rectangle gridClip = new Rectangle(0, 0, 100, 25); 

    clipGrid.selectedProperty().addListener(new ChangeListener<Boolean>() { 
     @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean wasClipped, Boolean clipped) { 
     if (clipped != null) { 
      if (clipped) { 
      grid.setClip(gridClip); 
      } else { 
      grid.setClip(null); 
      } 
     } 
     } 
    }); 

    restrictGridSize.selectedProperty().addListener(new ChangeListener<Boolean>() { 
     @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean wasClipped, Boolean clipped) { 
     if (clipped != null) { 
      if (clipped) { 
      // this does not work in our case. 
      // the minimum size of the grid components > the max size of the grid. 
      // so the grid expands in size to fit the minimum size of it's components anyway. 
      grid.setMaxSize(100, 25); 
      } else { 
      grid.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); 
      } 
     } 
     } 
    }); 

    clipHBoxes.selectedProperty().addListener(new ChangeListener<Boolean>() { 
     @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean wasClipped, Boolean clipped) { 
     if (clipped != null) { 
      if (clipped) { 
      for (Node gridCell: grid.getChildren()) { 
       Rectangle cellClip = new Rectangle(100, 12); 
       gridCell.setClip(cellClip); 
      } 
      } else { 
      for (Node gridCell: grid.getChildren()) { 
       gridCell.setClip(null); 
      } 
      } 
     } 
     } 
    }); 

    final VBox layout = new VBox(10); 
    clipWrappedHBoxes.selectedProperty().addListener(new ChangeListener<Boolean>() { 
     @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean wasClipped, Boolean clipped) { 
     if (clipped != null) { 
      if (clipped) { 
      layout.getChildren().set(0, gridWithClippedBoxes); 
      } else { 
      layout.getChildren().set(0, grid); 
      } 
     } 
     } 
    }); 

    noClip.fire(); 

    layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;"); 
    layout.getChildren().setAll(
     grid, 
     noClip, 
     restrictGridSize, 
     clipGrid, 
     clipHBoxes, 
     clipWrappedHBoxes 
    ); 

    stage.setScene(new Scene(layout)); 
    stage.show(); 
    } 

    private Region createHBox(String webColor) { 
    HBox box = new HBox(5); 
    box.setStyle("-fx-background-color: " + webColor + ";"); 
    for (String text: buttonText) { 
     box.getChildren().add(new Text(text)); 
    } 
    box.setOpacity(0.5); 

    return box; 
    }  

    private Region createClipWrappedHBox(String webColor) { 
    return new ClippedNode(createHBox(webColor), 100, 12); 
    } 

    class ClippedNode extends Region { 
    private final Node content; 
    private final double width; 
    private final double height; 

    ClippedNode(Node content, double width, double height) { 
     this.content = content; 
     this.width = width; 
     this.height = height; 

     content.setClip(new Rectangle(width, height)); 

     getChildren().setAll(content); 
    } 

    @Override protected double computeMinWidth(double d) { return width; } 
    @Override protected double computeMinHeight(double d) { return height; } 
    @Override protected double computePrefWidth(double d) { return width; } 
    @Override protected double computePrefHeight(double d) { return height; } 
    @Override protected double computeMaxWidth(double d) { return width; } 
    @Override protected double computeMaxHeight(double d) { return height; } 
    } 

    public static void main(String[] args) { Application.launch(args); } 
} 
+0

感謝負荷投入這麼多的精力!我想動態調整大小,因此我將剪輯「Rectangle」的高度/寬度限定爲「HBox」的高度/寬度,現在一切正常。 :) – Hbcdev 2013-03-19 14:13:00