3

我有一个JavaFX 2GUI,其中包括HBox填充一个GridPane. 我所有的组件都是动态调整大小的。这显示很好,没有问题。

第一个问题:我想剪辑它们所在单元格HBox边缘的内容GridPane,这样就不会显示任何溢出,但我不知道怎么做。我尝试将我的剪辑设置为HBox相同大小的矩形,但这不起作用。我猜是因为它使用了用于布局的尺寸,而不是显示的尺寸。我应该剪裁GridPane自身,还是至少使用它的属性?

第二个问题(加分):剪辑如何与平移和缩放交互Node

谢谢你的帮助。

4

1 回答 1

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; }
}

裁剪节点样本

下面提供了演示各种剪辑方法的完整可执行示例:

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); }
}
于 2013-03-18T23:22:08.573 回答