ScrollPane的ViewPort中的中心矩形

时间:2015-09-28 09:34:29

标签: java javafx-8

我的ImageView在选择特定过滤器时需要显示特定区域(即显示颜色为X的对象)。

表单的结构如下:ScrollPane - > Group - > ImageView

缩放工作,但我无法找到一种方法可靠地居中视图并显示包含已过滤对象的整个区域(Rectangle2D

public class FXMLController implements Initializable {

@FXML
private Group main;

@FXML
private ScrollPane scrollPane;

@FXML
private ImageView imgView;

@FXML
public void onMouseClicked(MouseEvent event) {
    switch (event.getButton()) {
        case PRIMARY:
            CalculateRectangle();
            break;
        case SECONDARY:
            Rectangle rect = new Rectangle(event.getX() - 50, event.getY() - 50, 100, 100);
            rect.setFill(Color.BLUE);
            rect.setStroke(Color.BLACK);
            main.getChildren().add(rect);
            break;
    }
}

private void CalculateRectangle() {
    ArrayList<Double> xMin, xMax, yMin, yMax;
    xMin = new ArrayList<>();
    xMax = new ArrayList<>();
    yMin = new ArrayList<>();
    yMax = new ArrayList<>();
    for (Node node : main.getChildren()) {
        if (!node.equals(imgView)) {
            xMin.add(node.getBoundsInParent().getMinX());
            xMax.add(node.getBoundsInParent().getMaxX());
            yMin.add(node.getBoundsInParent().getMinY());
            yMax.add(node.getBoundsInParent().getMaxY());
        }
    }
    if (!xMin.isEmpty() && !xMax.isEmpty() && !yMin.isEmpty() && !yMax.isEmpty()) {
        double xmin = Collections.min(xMin),
                xmax = Collections.max(xMax),
                ymin = Collections.min(yMin),
                ymax = Collections.max(yMax),
                width = xmax - xmin,
                height = ymax - ymin;
        ensureVisible(new Rectangle2D(xmin, ymin, width, height));
    }
}

private void ensureVisible(Rectangle2D rect) {
    double widthView = scrollPane.getViewportBounds().getWidth();
    double heightView = scrollPane.getViewportBounds().getHeight();
    double sx = widthView / rect.getWidth();
    double sy = heightView / rect.getHeight();
    double scaleFactor = Math.min(sx, sy) * 0.80;//ensure there's enough space for the rectangle + some margin
    main.getTransforms().setAll(new Scale(scaleFactor, scaleFactor));
    /********************************************************************************************/
    /**//*this results in (xMin,yMin) being visible while the rest depends on form size and zoom*/
    /**/scrollPane.setHvalue(rect.getMinX());
    /**/scrollPane.setVvalue(rect.getMinY());
    /********************************************************************************************/
}

@Override
public void initialize(URL location, ResourceBundle resources) {
    scrollPane.setVmax(imgView.getImage().getHeight());
    scrollPane.setHmax(imgView.getImage().getWidth());
}

}

Scene.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<ScrollPane fx:id="scrollPane" onKeyTyped="#onKeyPressed" prefHeight="300.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="stackoverflow.FXMLController">
    <content>
        <Group fx:id="main">
            <children>
                <ImageView fx:id="imgView" onMouseClicked="#onMouseClicked">
                    <viewport>
                        <Rectangle2D height="500.0" width="1000.0" />
                    </viewport>
                    <image>
                        <Image url="@../image.png" />
                    </image>
                </ImageView>
            </children>
        </Group>
    </content>
</ScrollPane>

0 个答案:

没有答案