在显示imageView的可调整大小的窗格中,我想选择多个矩形。
为此,我创建了一个类SelecTableImageViewPane。ImageViewPane和RubberBandSelection这两个类来自com.bitplan.javaFX项目,我是该项目的提交人。
当调整窗口的大小时,相关窗格的大小也会调整得很好,您可以从SelectableImageViewPaneDemo产生的调试输出和下面的示例截图中看到这一点。不幸的是,选择矩形没有调整大小/重新定位。
package com.bitplan.javafx;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
/**
* an ImageViewPane with a RubberBandSelection that properly resizes the rectangles
* @author wf
*
*/
public class SelectableImageViewPane extends StackPane {
protected static Logger LOGGER = Logger.getLogger("com.bitplan.javafx");
public static boolean debug=true;
private RubberBandSelection selection;
private ImageViewPane imageViewPane;
private Pane glassPane;
/**
* get my selection
* @return
*/
public RubberBandSelection getSelection() {
return selection;
}
/**
* show the bound of the given node with the given title
* @param title
* @param n
*/
public void showBounds(String title,Node n) {
if (debug) {
Bounds b = n.getLayoutBounds();
LOGGER.log(Level.INFO,String.format("%s: min %.0f,%.0f max %.0f,%.0f",title,b.getMinX(),b.getMinY(),b.getMaxX(),b.getMaxY()));
}
}
@Override
protected void layoutChildren() {
super.layoutChildren();
int index=1;
if (debug) {
showBounds("pane",this);
showBounds("imageViewPane",imageViewPane);
showBounds("glassPane",glassPane);
showBounds("imageView",imageViewPane.imageViewProperty().get());
}
for (Node n:selection.selected) {
showBounds(""+(index++),n);
}
}
/**
* create me
* @param imageView
*/
public SelectableImageViewPane(ImageView imageView) {
imageViewPane=new ImageViewPane(imageView);
getChildren().add(imageViewPane);
StackPane.setAlignment(imageViewPane, Pos.CENTER);
glassPane = new AnchorPane();
glassPane.setStyle("-fx-background-color: rgba(0, 0, 0, 0.1);");
getChildren().add(glassPane);
//glassPane.prefWidthProperty().bind(imageViewPane.widthProperty());
//glassPane.prefHeightProperty().bind(imageViewPane.heightProperty());
selection = new RubberBandSelection(glassPane);
selection.setSelectButton(true);
}
}
Bounds rB = s.relativeBounds;
double w = getWidth();
double h=getHeight();
double minX=rB.getMinX()*w;
double minY=rB.getMinY()*h;
double width=rB.getWidth()*w;
double height=rB.getHeight()*h;
layoutInArea(s.node, minX,minY,width,height, 0, HPos.LEFT,
VPos.TOP);
该解决方案工作得更好,但仍然存在一些问题,可能涉及父级中的x/y偏移量。
更新的SelectableImageViewPane
package com.bitplan.javafx;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.bitplan.javafx.RubberBandSelection.Selection;
import javafx.geometry.Bounds;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
/**
* an ImageViewPane with a RubberBandSelection that properly resizes the
* rectangles
*
* @author wf
*
*/
public class SelectableImageViewPane extends StackPane {
protected static Logger LOGGER = Logger.getLogger("com.bitplan.javafx");
public static boolean debug = true;
private RubberBandSelection selection;
private ImageViewPane imageViewPane;
private Pane glassPane;
/**
* get my selection
*
* @return
*/
public RubberBandSelection getSelection() {
return selection;
}
/**
* show the bound of the given node with the given title
*
* @param title
* @param n
*/
public void showBounds(String title, Node n) {
if (debug) {
Bounds b = n.getLayoutBounds();
LOGGER.log(Level.INFO, String.format("%s: min %.0f,%.0f max %.0f,%.0f", title, b.getMinX(), b.getMinY(),
b.getMaxX(), b.getMaxY()));
}
}
@Override
protected void layoutChildren() {
super.layoutChildren();
int index = 1;
if (debug) {
showBounds("pane", this);
showBounds("imageViewPane", imageViewPane);
showBounds("glassPane", glassPane);
showBounds("imageView", imageViewPane.imageViewProperty().get());
}
for (Selection s : selection.selected.values()) {
if (debug) {
showBounds("" + (index++), s.node);
LOGGER.log(Level.INFO, s.asPercent());
}
Bounds rB = s.relativeBounds;
double w = getWidth();
double h=getHeight();
double minX=rB.getMinX()*w;
double minY=rB.getMinY()*h;
double width=rB.getWidth()*w;
double height=rB.getHeight()*h;
layoutInArea(s.node, minX,minY,width,height, 0, HPos.LEFT,
VPos.TOP);
}
}
/**
* create me
*
* @param imageView
*/
public SelectableImageViewPane(ImageView imageView) {
imageViewPane = new ImageViewPane(imageView);
getChildren().add(imageViewPane);
StackPane.setAlignment(imageViewPane, Pos.CENTER);
glassPane = new AnchorPane();
glassPane.setStyle("-fx-background-color: rgba(0, 0, 0, 0.1);");
getChildren().add(glassPane);
// glassPane.prefWidthProperty().bind(imageViewPane.widthProperty());
// glassPane.prefHeightProperty().bind(imageViewPane.heightProperty());
selection = new RubberBandSelection(glassPane);
selection.setSelectButton(true);
}
}
有两个主要因素使其发挥作用:
请注意ChrisCamacho对原始代码有两处更改:
package com.bitplan.javafx;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.Observable;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.scene.Parent;
import javafx.scene.control.Control;
import javafx.scene.layout.Pane;
/**
* We want a Pane that will automatically resize its components The components
* width height and position are all expressed as a relative of the width and
* height of the Pane from 0.0 to 1.0 As the Pane resizes the position and sizes
* will all remain relative to the Pane's new width and height. Aspect ratio is
* not respected
*
* see https://gist.github.com/chriscamacho/4f8b2e3e8f8340278b7c
*
* @author chriscamacho
* @author wf - modified to relative instead of percent
*
*/
public class RelativePane extends Pane implements RelativeSizer {
protected static Logger LOGGER = Logger.getLogger("com.bitplan.javafx");
public static boolean debug=false;
/**
* helper class to keep track of relative position
*/
public class ControlBundle {
public double rx, ry, rw, rh;
public Control control;
/**
* construct me for the given control c and the given relative positions
*
* @param c
* @param rX
* @param rY
* @param rW
* @param rH
*/
ControlBundle(Control c, double rX, double rY, double rW, double rH) {
control = c;
rx = rX;
ry = rY;
rw = rW;
rh = rH;
}
}
Map<Control, ControlBundle> controls = new HashMap<Control, ControlBundle>();
/**
* create a relative Pane
*/
public RelativePane() {
super();
widthProperty().addListener(o -> sizeListener(o));
heightProperty().addListener(o -> sizeListener(o));
}
/**
* show the bounds of the given node with the given title
*
* @param title
* @param b
*/
public static void showBoundsPercent(String title, Bounds b) {
LOGGER.log(Level.INFO,
String.format("%s: min %.0f%%,%.0f%% max %.0f%%,%.0f%%", title,
b.getMinX() * 100.0, b.getMinY() * 100.0, b.getMaxX() * 100.0,
b.getMaxY() * 100.0));
}
/**
* show the given bounds with the given title
*
* @param title
* @param b
*/
public static void showBounds(String title, Bounds b) {
LOGGER.log(Level.INFO, String.format("%s: min %.0f,%.0f max %.0f,%.0f",
title, b.getMinX(), b.getMinY(), b.getMaxX(), b.getMaxY()));
}
/**
* listen to a change of the given observable
* @param o
*/
void sizeListener(Observable o) {
int index=0;
for (ControlBundle cb : controls.values()) {
index++;
double w = getWidth() * cb.rw;
double h = getHeight() * cb.rh;
double x = getWidth() * cb.rx;
double y = getHeight() * cb.ry;
if (debug) {
showBoundsPercent("r"+index,new BoundingBox(cb.rx,cb.ry,cb.rw,cb.rh));
showBounds("a"+index,new BoundingBox(x,y,w,h));
}
cb.control.setPrefWidth(w);
cb.control.setMinWidth(w);
cb.control.setMaxWidth(w);
cb.control.setPrefHeight(h);
cb.control.setMinHeight(h);
cb.control.setMaxHeight(h);
cb.control.setLayoutX(x);
cb.control.setLayoutY(y);
}
}
/**
* add a control with the given percentages
*
* @param ctrl
* @param x
* @param y
* @param w
* @param h
*/
public void addControl(Control ctrl, double x, double y, double w, double h) {
this.getChildren().add(ctrl);
controls.put(ctrl, new ControlBundle(ctrl, x, y, w, h));
}
public void removeControl(Control ctrl) {
this.getChildren().remove(ctrl);
controls.remove(ctrl);
}
@Override
public Parent getSizer() {
return this;
}
}
我有两个问题 2.最初VBox会占据全场景区域,如何让它(重新定位)到场景的半底?
我看到下面的链接-https://stackoverflow.com/questions/5302197/javafx-bug-is-there-a-way-to-force-repaint-this-not-a-single-threading-pr调用requestLayout似乎没有帮助。我还尝试在图中的各个节点上调用impl_updatePG和impl_transformsChanged。
我们在SVN中有以下项目结构,其中父项目(不是聚合器)定义了公共配置。父级被单独管理和释放。 因此,基本上每个实际项目(project1、project2)都被用作其子项目的聚合器。公共配置设置(Java编译器版本、其他插件)保留在父级中,在所有项目(project1,project2)中,父级用作Maven。 我想在父级中定义的设置之一是Subversion的SCM URL,例如父级pom.xm
问题内容: 在我的应用中,我必须经常在两种布局之间切换。错误在下面发布的布局中发生。 第一次调用布局时,没有发生任何错误,一切都很好。然后,当我调用不同的布局(空白),然后再次调用我的布局时,出现以下错误: 我的布局代码如下所示: 我知道之前曾有人问过这个问题,但对我来说没有帮助。 问题答案: 错误消息说明你应该做什么。
我有两个组成部分: 父组件 子组件 我试图从Parent调用child的方法,我尝试了这种方法,但无法得到结果: 有没有办法从父级调用子级的方法? 注意:子组件和父组件在两个不同的文件中。
问题内容: 我有两个组成部分。 父组件 子组件 我试图从父级调用孩子的方法,我尝试过这种方法,但没有得到结果 有没有一种方法可以从父级调用子级的方法? 注意:子组件和父组件位于两个不同的文件中 问题答案: 首先,让我表示,这通常 不是 在React领域中解决问题的方法。通常,您要做的是将功能传递给道具中的子代,并传递事件中的子代的通知(或者更好的是:)。 但是,如果 必须 在子组件上公开命令式方法