下面列出了怎么用javafx.scene.transform.Scale的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public List<? extends Shape> getHandles(Translate translate, Scale scale, ReadOnlyObjectProperty<Color> colorProperty) {
List<Shape> handles = new ArrayList<>();
IntStream.range(0, getPoints().size() / 2).forEach(idx -> {
Handle handle = new Handle(idx, getPoints());
handles.add(handle);
// Maintain constant handle size at different zoom level
scale.addEventHandler(TransformChangedEvent.TRANSFORM_CHANGED, event -> {
handle.setRadius(HANDLE_RADIUS / scale.getX());
});
handle.fillProperty().bind(colorProperty);
handle.setRadius(HANDLE_RADIUS / scale.getX());
handle.getTransforms().addAll(translate, scale);
});
return handles;
}
@Override
public List<? extends Shape> getHandles(Translate translate, Scale scale, ReadOnlyObjectProperty<Color> colorProperty) {
// 4 corner resize handles
List<Rectangle> handles = Arrays.asList(new Rectangle[]{
createHandle(Location.NW, cursorNW),
createHandle(Location.NE, cursorNE),
createHandle(Location.SE, cursorSE),
createHandle(Location.SW, cursorSW)});
// Maintain constant handle size at different zoom level
handles.forEach(handle -> {
scale.addEventHandler(TransformChangedEvent.TRANSFORM_CHANGED, event -> {
handle.setWidth(HANDLE_SIZE / scale.getX());
handle.setHeight(HANDLE_SIZE / scale.getY());
});
handle.fillProperty().bind(colorProperty);
handle.setWidth(HANDLE_SIZE / scale.getX());
handle.setHeight(HANDLE_SIZE / scale.getY());
handle.getTransforms().addAll(translate, scale);
});
return handles;
}
/**
* Wrap a given Node (e.g. a Pin button) in a {@link StackPane} to be placed on to the map. Applies a scaling function (used to scales it
* relative to the current zoom factor) and translations (to keep it at a given world space position and centered).
*/
static StackPane wrapGui(Node node, Vector2dc position, DoubleBinding scale, DisplayViewport viewport) {
StackPane stack = new StackPane(node);
Translate center = new Translate();
center.xProperty().bind(stack.widthProperty().multiply(-0.5));
center.yProperty().bind(stack.heightProperty().multiply(-0.5));
if (position != null)
stack.getTransforms().add(new Translate(position.x(), position.y()));
if (scale != null) {
Scale scaleTransform = new Scale();
scaleTransform.xProperty().bind(scale);
scaleTransform.yProperty().bind(scale);
stack.getTransforms().add(scaleTransform);
}
stack.getTransforms().add(center);
stack.setVisible(false);
stack.setPickOnBounds(false);
stack.setOpacity(0.0);
return stack;
}
@Override
public Region getGraphic(Graph graph) {
final double width = 50;
final double height = 50;
final Polygon view = new Polygon(width / 2, 0, width, height, 0, height);
view.setStroke(Color.RED);
view.setFill(Color.RED);
final Pane pane = new Pane(view);
pane.setPrefSize(50, 50);
final Scale scale = new Scale(1, 1);
view.getTransforms().add(scale);
scale.xProperty().bind(pane.widthProperty().divide(50));
scale.yProperty().bind(pane.heightProperty().divide(50));
CellGestures.makeResizable(pane);
return pane;
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Digital Clock");
Group root = new Group();
Scene scene = new Scene(root, 480, 412);
// add background image
ImageView background = new ImageView(new Image(getClass().getResourceAsStream("DigitalClock-background.png")));
// add digital clock
clock = new Clock(Color.ORANGERED, Color.rgb(50,50,50));
clock.setLayoutX(45);
clock.setLayoutY(186);
clock.getTransforms().add(new Scale(0.83f, 0.83f, 0, 0));
// add background and clock to sample
root.getChildren().addAll(background, clock);
primaryStage.setScene(scene);
primaryStage.show();
}
/** Update lines that indicate model's size in edit mode */
private void updateModelSizeIndicators()
{
int width = model.propWidth().getValue();
int height = model.propHeight().getValue();
final ObservableList<Transform> transforms = widget_parent.getTransforms();
if (transforms.size() > 0 && transforms.get(0) instanceof Scale)
{
final Scale scale = (Scale) transforms.get(0);
width *= scale.getX();
height *= scale.getY();
}
horiz_bound.setStartY(height);
horiz_bound.setEndX(width);
horiz_bound.setEndY(height);
vert_bound.setStartX(width);
vert_bound.setEndY(height);
vert_bound.setEndX(width);
}
private void print(final Node node)
{
try
{
// Select printer
final PrinterJob job = Objects.requireNonNull(PrinterJob.createPrinterJob(), "Cannot create printer job");
final Scene scene = Objects.requireNonNull(node.getScene(), "Missing Scene");
if (! job.showPrintDialog(scene.getWindow()))
return;
// Get Screenshot
final WritableImage screenshot = node.snapshot(null, null);
// Scale image to full page
final Printer printer = job.getPrinter();
final Paper paper = job.getJobSettings().getPageLayout().getPaper();
final PageLayout pageLayout = printer.createPageLayout(paper,
PageOrientation.LANDSCAPE,
Printer.MarginType.DEFAULT);
final double scaleX = pageLayout.getPrintableWidth() / screenshot.getWidth();
final double scaleY = pageLayout.getPrintableHeight() / screenshot.getHeight();
final double scale = Math.min(scaleX, scaleY);
final ImageView print_node = new ImageView(screenshot);
print_node.getTransforms().add(new Scale(scale, scale));
// Print off the UI thread
JobManager.schedule(Messages.Print, monitor ->
{
if (job.printPage(print_node))
job.endJob();
});
}
catch (Exception ex)
{
ExceptionDetailsErrorDialog.openError(node, Messages.Print, Messages.PrintErr, ex);
}
}
@Override
public void start(Stage primaryStage) throws Exception {
final Polygon p = new Polygon(10, 30, 20, 20, 20, 40);
p.setFill(Color.RED);
p.setStroke(Color.BLACK);
final Rectangle r = new Rectangle();
r.setFill(new Color(0, 0, 1, 0.5));
r.setX(p.getLayoutBounds().getMinX());
r.setY(p.getLayoutBounds().getMinY());
r.setWidth(p.getLayoutBounds().getWidth());
r.setHeight(p.getLayoutBounds().getHeight());
Group g = new Group(r, p);
g.getTransforms().add(new Scale(10, 10));
Scene scene = new Scene(g, 500, 500);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
@Override
protected void layoutChildren() {
// calculate scale
double scale = getWidth() / computePrefWidth(-1);
getChildren().stream().filter(child -> child instanceof Region).forEach(child -> {
Region region = (Region) child;
if (region.getShape() != null) {
region.resize(
region.getShape().getLayoutBounds().getMaxX(),
region.getShape().getLayoutBounds().getMaxY()
);
region.getTransforms().setAll(new Scale(scale, scale, 0, 0));
} else {
region.autosize();
}
});
}
/**
* Creates a thumbnail from the given selection in the given file.
* @param templateFile The file of the future thumbnail.
* @param selection The set of shapes composing the template.
*/
private void createTemplateThumbnail(final File templateFile, final javafx.scene.Group selection) {
final Bounds bounds = selection.getBoundsInParent();
final double scale = 70d / Math.max(bounds.getWidth(), bounds.getHeight());
final WritableImage img = new WritableImage((int) (bounds.getWidth() * scale), (int) (bounds.getHeight() * scale));
final SnapshotParameters snapshotParameters = new SnapshotParameters();
snapshotParameters.setFill(Color.WHITE);
snapshotParameters.setTransform(new Scale(scale, scale));
selection.snapshot(snapshotParameters, img);
final BufferedImage bufferedImage = SwingFXUtils.fromFXImage(img, null);
try {
ImageIO.write(bufferedImage, "png", templateFile); //NON-NLS
}catch(final IOException ex) {
BadaboomCollector.INSTANCE.add(ex);
}
bufferedImage.flush();
}
private void initModel(Annotation model) {
scale = new Scale(1, 1);
translate = new Translate(PADDING, PADDING);
rotate = new Rotate();
board.getTransforms().setAll(scale, rotate);
scale.addEventHandler(TransformChangedEvent.TRANSFORM_CHANGED, event -> {
// Maintain constant padding at different zoom level
board.setPadding(new Insets(max(PADDING / scale.getX(), PADDING / scale.getY())));
canvas.setWidth(imageView.getBoundsInLocal().getWidth());
canvas.setHeight(imageView.getBoundsInLocal().getHeight());
});
scale.setX(1);
scale.setY(1);
rotate.setAngle(0);
selectedObjectProperty.setValue(null);
tagCoordsProperty.set("");
objectsProperty.clear();
hintsProperty.clear();
imageView.setImage(model == null ? null : model.getSize().getImage());
imageView.setCache(true);
if (model != null && model.getObjects().size() > 0) {
model.getObjects().forEach(obj -> createObjectTag(obj));
statusProperty.set(MessageFormat.format(bundle.getString("msg.objectsCount"), model.getObjects().size()));
}
else {
statusProperty.set(bundle.getString("msg.noObjects"));
}
findHints();
}
public ContentResizerPane(Node content) {
this.content = content;
getChildren().add(content);
Scale scale = new Scale(1, 1);
content.getTransforms().add(scale);
resizeFActor.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
scale.setX(newValue.doubleValue());
scale.setY(newValue.doubleValue());
requestLayout();
});
}
public PinDecoration(DisplayViewport viewport) {
this.viewport = Objects.requireNonNull(viewport);
this.viewport.scaleProperty.addListener(new WeakChangeListener<>(this));
world = new AnchorPane();
world.getStylesheets().add("/de/piegames/blockmap/gui/decoration/pins.css");
{
Scale s = new Scale();
s.xProperty().bind(viewport.scaleProperty);
s.yProperty().bind(viewport.scaleProperty);
Translate t = new Translate();
t.xProperty().bind(Bindings.createDoubleBinding(() -> viewport.translationProperty.get().x(), viewport.translationProperty));
t.yProperty().bind(Bindings.createDoubleBinding(() -> viewport.translationProperty.get().y(), viewport.translationProperty));
world.getTransforms().add(s);
world.getTransforms().add(t);
}
world.setPickOnBounds(false);
getChildren().add(world);
setMinSize(0, 0);
setPrefSize(0, 0);
setPickOnBounds(false);
{
final Rectangle outputClip = new Rectangle();
this.setClip(outputClip);
this.layoutBoundsProperty().addListener((ov, oldValue, newValue) -> {
outputClip.setWidth(newValue.getWidth());
outputClip.setHeight(newValue.getHeight());
});
}
visiblePins.addListener((InvalidationListener) e -> executeUpdate.requestExecution());
}
/**
* Scales the game rendering (as defined by gameResolution) to fill the current
* stage size. <b>Should be called whenever stage size or game resolution is
* changed</b> - currently called only when toggling fullscreen mode.
*/
private void scaleResolution() {
canvas.getTransforms().clear();
canvas.setTranslateX(-scene.getWidth() / 2 + gameResolution.x / 2); // recenters after scale
canvas.setTranslateY(-scene.getHeight() / 2 + gameResolution.y / 2); // recenters after scale
if (!(scene.getWidth() == gameResolution.x && scene.getHeight() == gameResolution.y)) {
canvas.setWidth(gameResolution.x);
canvas.setHeight(gameResolution.y);
width = (int) gameResolution.x;
height = (int) gameResolution.y;
final double scaleX = scene.getWidth() / gameResolution.x;
final double scaleY = scene.getHeight() / gameResolution.y;
canvas.getTransforms().setAll(new Scale(scaleX, scaleY)); // scale canvas
}
}
public DigitalClock() {
super(480, 412);
// add background image
ImageView background = new ImageView(new Image(getClass().getResourceAsStream("DigitalClock-background.png")));
// add digital clock
clock = new Clock(Color.ORANGERED, Color.rgb(50,50,50));
clock.setLayoutX(45);
clock.setLayoutY(186);
clock.getTransforms().add(new Scale(0.83f, 0.83f, 0, 0));
// add background and clock to sample
getChildren().addAll(background, clock);
}
public DigitalClock() {
super(480, 412);
// add background image
ImageView background = new ImageView(new Image(getClass().getResourceAsStream("DigitalClock-background.png")));
// add digital clock
clock = new Clock(Color.ORANGERED, Color.rgb(50,50,50));
clock.setLayoutX(45);
clock.setLayoutY(186);
clock.getTransforms().add(new Scale(0.83f, 0.83f, 0, 0));
// add background and clock to sample
getChildren().addAll(background, clock);
}
/** @return Zoom factor, 1.0 for 1:1 */
public double getZoom()
{
final List<Transform> transforms = widget_parent.getTransforms();
if (transforms.isEmpty() ||
transforms.size() > 1 ||
! (transforms.get(0) instanceof Scale))
return 1.0;
// Have one 'scale'
final Scale scale = (Scale) transforms.get(0);
// Expect scaling in X == Y, but just in case return average
return ( scale.getX() + scale.getY() ) / 2.0;
}
@Override
public ScrollPane createJFXNode() throws Exception
{
// inner.setScaleX() and setScaleY() zoom from the center
// and not the top-left edge, requiring adjustments to
// inner.setTranslateX() and ..Y() to compensate.
// Using a separate Scale transformation does not have that problem.
// See http://stackoverflow.com/questions/10707880/javafx-scale-and-translate-operation-results-in-anomaly
inner = new Pane();
inner.getTransforms().add(zoom = new Scale());
scroll = new ScrollPane(inner);
// By default it seems that the minimum size is set to 36x36.
// This will make the border (if visible) not smaller that this minimum size
// even if the widget is actually smaller.
scroll.setMinSize(1, 1);
// Removing 1px border around the ScrollPane's content. See https://stackoverflow.com/a/29376445
scroll.getStyleClass().addAll("embedded_display", "edge-to-edge");
// Panning tends to 'jerk' the content when clicked
// scroll.setPannable(true);
// If there are scrollbars, the scroll pane may react
// to the mouse wheel and scroll the content.
// Unfortunately it will also react to the mouse wheel
// when there are no scrollbars and might end up with
// the content moved out of the viewport.
// --> Suppress scrolling unless we have scrollbars.
scroll.addEventFilter(ScrollEvent.ANY, event ->
{
if (model_widget.propResize().getValue() != Resize.None)
event.consume();
});
return scroll;
}
/**
* Save to png.
*
* @param f
* the f
*/
public void saveToPng(File f) {
String fName = f.getAbsolutePath();
if (!fName.toLowerCase().endsWith(".png")) {
fName += ".png";
}
int snWidth = 1024;
int snHeight = 1024;
double realWidth = getRoot().getBoundsInLocal().getWidth();
double realHeight = getRoot().getBoundsInLocal().getHeight();
double scaleX = snWidth / realWidth;
double scaleY = snHeight / realHeight;
double scale = Math.min(scaleX, scaleY);
PerspectiveCamera snCam = new PerspectiveCamera(false);
snCam.setTranslateZ(-200);
SnapshotParameters snapshotParameters = new SnapshotParameters();
snapshotParameters.setTransform(new Scale(scale, scale));
snapshotParameters.setCamera(snCam);
snapshotParameters.setDepthBuffer(true);
snapshotParameters.setFill(Color.TRANSPARENT);
WritableImage snapshot = new WritableImage(snWidth, (int) (realHeight * scale));
getRoot().snapshot(snapshotParameters, snapshot);
try {
ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", new File(fName));
} catch (IOException ex) {
ex.printStackTrace();
Log.error(ex.getMessage());
}
}
/**
* Creates the {@link Pane} that is used to display nested content.
*
* @return The {@link Pane} that is used to display nested content.
*/
private Pane createNestedContentPane() {
Pane nestedChildrenPaneScaled = new Pane();
Scale scale = new Scale();
nestedChildrenPaneScaled.getTransforms().add(scale);
scale.setX(DEFAULT_NESTED_CHILDREN_ZOOM_FACTOR);
scale.setY(DEFAULT_NESTED_CHILDREN_ZOOM_FACTOR);
return nestedChildrenPaneScaled;
}
public JFXPopupSkin(JFXPopup control) {
this.control = control;
// set scale y to 0.01 instead of 0 to allow layout of the content,
// otherwise it will cause exception in traverse engine, when focusing the 1st node
scale = new Scale(1, 0.01, 0, 0);
popupContent = control.getPopupContent();
container.getStyleClass().add("jfx-popup-container");
container.setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
container.getChildren().add(popupContent);
container.getTransforms().add(scale);
container.setOpacity(0);
root = JFXDepthManager.createMaterialNode(container, 4);
animation = getAnimation();
}
/**
* will retrieve icons from the glyphs map for a certain glyphName
*
* @param glyphName the glyph name
* @return SVGGlyph node
*/
public static SVGGlyph getIcoMoonGlyph(String glyphName) throws Exception{
SVGGlyphBuilder builder = glyphsMap.get(glyphName);
if(builder == null) throw new Exception("Glyph '" + glyphName + "' not found!");
SVGGlyph glyph = builder.build();
// we need to apply transformation to correct the icon since
// its being inverted after importing from icomoon
glyph.getTransforms().add(new Scale(1, -1));
Translate height = new Translate();
height.yProperty().bind(Bindings.createDoubleBinding(() -> -glyph.getHeight(), glyph.heightProperty()));
glyph.getTransforms().add(height);
return glyph;
}
private void resizeMapControl() {
double scale = Math.min(mapCanvasPane.getWidth() / mapControl.getSize(), mapCanvasPane.getHeight() / mapControl.getSize());
double sw = mapControl.getSize() * scale;
double dx = mapCanvasPane.getWidth() - sw;
double dy = mapCanvasPane.getHeight() - sw;
mapCanvasPane.getTransforms().clear();
mapCanvasPane.getTransforms().add(new Scale(scale, scale));
mapCanvasPane.getTransforms().add(new Translate(0.5 * dx / scale, 0.5 * dy / scale));
}
public MapControl() {
mapImage = new Image(getClass().getResourceAsStream("/images/minimap_686.jpg"));
double scale = getSize() / mapImage.getWidth();
background = new ImageView(mapImage);
background.getTransforms().add(new Scale(scale, scale));
getChildren().add(background);
icons = new Group();
getChildren().add(icons);
}
@Override
protected void layoutChildren() {
// calculate scale
double scale = getWidth() / computePrefWidth(-1);
getChildren().stream().filter(child -> child instanceof Region).forEach(child -> {
Region region = (Region) child;
if (region.getShape() != null) {
region.resize(region.getShape().getLayoutBounds().getMaxX(),
region.getShape().getLayoutBounds().getMaxY());
region.getTransforms().setAll(new Scale(scale, scale, 0, 0));
} else {
region.autosize();
}
});
}
/**
* Initializes the menu bar.
*/
private void initializeMenuBar() {
scaleTransform = new Scale(currentZoomFactor, currentZoomFactor, 0, 0);
scaleTransform.yProperty().bind(scaleTransform.xProperty());
graphEditor.getView().getTransforms().add(scaleTransform);
final ToggleGroup skinGroup = new ToggleGroup();
skinGroup.getToggles().addAll(defaultSkinButton, treeSkinButton, titledSkinButton);
final ToggleGroup connectionStyleGroup = new ToggleGroup();
connectionStyleGroup.getToggles().addAll(gappedStyleButton, detouredStyleButton);
final ToggleGroup connectorTypeGroup = new ToggleGroup();
connectorTypeGroup.getToggles().addAll(inputConnectorTypeButton, outputConnectorTypeButton);
final ToggleGroup positionGroup = new ToggleGroup();
positionGroup.getToggles().addAll(leftConnectorPositionButton, rightConnectorPositionButton);
positionGroup.getToggles().addAll(topConnectorPositionButton, bottomConnectorPositionButton);
graphEditor.getProperties().gridVisibleProperty().bind(showGridButton.selectedProperty());
graphEditor.getProperties().snapToGridProperty().bind(snapToGridButton.selectedProperty());
minimapButton.setGraphic(AwesomeIcon.MAP.node());
initializeZoomOptions();
final ListChangeListener<? super GNode> selectedNodesListener = change -> {
checkConnectorButtonsToDisable();
};
graphEditor.getSelectionManager().getSelectedNodes().addListener(selectedNodesListener);
checkConnectorButtonsToDisable();
}
public Axes(double scale) {
axisX.getTransforms().addAll(new Rotate(90, Rotate.Z_AXIS), new Translate(0, 30, 0));
axisX.setMaterial(new PhongMaterial(Color.RED));
axisY.getTransforms().add(new Translate(0, 30, 0));
axisY.setMaterial(new PhongMaterial(Color.GREEN));
axisZ.setMaterial(new PhongMaterial(Color.BLUE));
axisZ.getTransforms().addAll(new Rotate(90, Rotate.X_AXIS), new Translate(0, 30, 0));
getChildren().addAll(axisX, axisY, axisZ);
getTransforms().add(new Scale(scale, scale, scale));
}
private Group getThingsGroup(boolean infraredOn, boolean effectsOn) {
Group things = new Group();
things.getChildren().addAll(getNodesForThingsInOrder(infraredOn, effectsOn));
if (VisualDebugger.DEBUG)
things.getChildren().add(getVisualDebuggingSegments());
things.getTransforms().add(new Translate(-viewport.getPositionEC().x, -viewport.getPositionEC().y));
things.getTransforms().add(
new Scale(viewport.getZoomLevel(), viewport.getZoomLevel(), viewport.getPositionEC().x, viewport.getPositionEC().y));
return things;
}
public Node toNode(boolean infraredOn) {
Node result = infraredOn ? infraredBackground : background;
double minimumZoomLevelToSeeSpeckles = 0.20;
if (viewport.getZoomLevel() <= minimumZoomLevelToSeeSpeckles)
return null;
result.getTransforms().clear();
result.getTransforms().add(new Translate(-viewport.getPositionEC().x, -viewport.getPositionEC().y));
result.getTransforms().add(
new Scale(viewport.getZoomLevel(), viewport.getZoomLevel(), viewport.getPositionEC().x, viewport.getPositionEC().y));
return result;
}
/**
* @return A writable image that contains given views (not null).
*/
private @NotNull BufferedImage createRenderedImage() {
final Group views = canvas.getViews();
final Bounds bounds = views.getBoundsInParent();
final double scale = 3d;
final WritableImage img = new WritableImage((int) (bounds.getWidth() * scale), (int) (bounds.getHeight() * scale));
final SnapshotParameters snapshotParameters = new SnapshotParameters();
snapshotParameters.setFill(Color.WHITE);
snapshotParameters.setTransform(new Scale(scale, scale));
views.snapshot(snapshotParameters, img);
return SwingFXUtils.fromFXImage(img, null);
}