2013-03-18 82 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