2

我在 JavaFX 中遇到了一个问题。

这就是 Jasperserver(服务器)、Adhoc-Model(服务器模型之一)中显示的内容。

图片:Jasperserver 即席布局

图片:内部 HTML 代码

可以看到,粉色区域,是一种 HTML <li> Tag。它可以显示具有非矩形形状的 UI。喜欢俄罗斯方块吗?

但是,我试图在 JavaFX 中做同样的事情但失败了。

我使用FlowPane作为窗格A,并在窗格A中放入一些标签。然后我使用一点FlowPane作为窗格B,也将一些标签放入窗格B。最后,我将窗格B放入窗格A。

如下图所示。

图片:显示在 JavaFX 中

如您所见,我未能显示具有非矩形形状的窗格 B。而且我认为要做到这一点并不容易。

有谁能够帮我 ?您的回答将不胜感激。非常感谢。

如果有人需要我的代码,请告诉我。我将重写一些简单的代码并放在这里。

4

1 回答 1

0

非常感谢@James_D。

我编写了一个自定义窗格,它扩展了 FlowPane,并重写了 layoutChildren() 函数。

有用 !

在此处输入图像描述

以下是我的代码:

import java.util.ArrayList;
import java.util.List;

import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;

public class LayoutFlowPane extends FlowPane {

    private class Child {
        Node node;
        double x, y, w, h;
        double blft, midy;
        public Child(Node node,
                double x, double y, double w, double h,
                double blft, double midy) {
            super();
            this.node = node;
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
            this.blft = blft;
            this.midy = midy;
        }
    }

    private List<Child> children = new ArrayList<>();
    private List<Double> midys = new ArrayList<>();

    public LayoutFlowPane() {
        super();
    }

    @Override protected void layoutChildren() {

        super.layoutChildren();

        Insets insets = getInsets();
        double width = getWidth();
        double height = getHeight();
        double top = insets.getTop();
        double left = insets.getLeft();
        double bottom = insets.getBottom();
        double right = insets.getRight();
        double maxw = width - left - right;
        double maxh = height - top - bottom;
        double hgap = snapSpace(this.getHgap());
        double vgap = snapSpace(this.getVgap());

        storeChildren();

        adjustChildren(maxw, maxh, hgap, vgap);

        children.forEach(child -> {
            layoutInArea(
                    child.node, child.x, child.y, 
                    child.w, child.h, child.blft, getMargin(child.node),
                    getColumnHalignmentInternal(), getRowValignmentInternal()
            );
        });
    }

    private void storeChildren() {
        children = new ArrayList<>();
        for (int i = 0; i < getChildren().size(); i ++) {
            Node child = getChildren().get(i);
            double x = child.getLayoutX();
            double y = child.getLayoutY();
            double w = 0;
            double h = 0;
            if (child instanceof Region) {
                Region region = (Region) child;
                w = region.getWidth();
                h = region.getHeight();
            } else {
                throw new UnknowTypeException("Unknow type found.");
            }
            double blft = child.getBaselineOffset();
            double midy = (y + y + h) / 2;
            Child newChild = new Child(child, x, y, w, h, blft, midy);
            children.add(newChild);
        }
        midys = new ArrayList<>();
        for (int i = 0; i < children.size(); i ++) {
            Child child = children.get(i);
            if (midys.isEmpty() || midys.get(midys.size()-1) != child.midy) {
                midys.add(child.midy);
            }
        }
    }

    private void adjustChildren(double maxw, double maxh, double hgap, double vgap) {
        for (int i = 1; i < children.size(); i ++) { // begin with 1
            Child pc = children.get(i-1);
            Child ch = children.get(i);
            boolean bothGridPane = (pc.node instanceof GridPane) && (ch.node instanceof GridPane); 
            double x = pc.x + pc.w + (bothGridPane ? 0 : hgap);
            double midy;
            if (x + ch.w <= maxw) { // ThisLine
                midy = pc.midy;
                ch.x = x;
                ch.y = gety(ch.y, ch.midy, midy);
                ch.midy = midy;
            } else { // NextLine
                midy = getNextMidy(pc.midy);
                ch.x = children.get(0).x;
                ch.y = gety(ch.y, ch.midy, midy);
                ch.midy = midy;
            }
        }
    }

    private double getNextMidy(double midy) {
        for (int i = 0; i < midys.size(); i ++) {
            if (i + 1 < midys.size() && midys.get(i) == midy && midys.get(i+1) != midy) {
                return midys.get(i+1);
            } else if (i + 1 == midys.size() && midys.get(i) == midy) {
                return midys.get(i);
            }
        }
        throw new NotFoundException("Next midy not found.");
    }

    private double gety(double oldy, double oldMidy, double newMidy) {
        return oldy + (newMidy - oldMidy);
    }

    private HPos getColumnHalignmentInternal() {
        HPos localPos = getColumnHalignment();
        return null == localPos ? HPos.LEFT : localPos;
    }

    private VPos getRowValignmentInternal() {
        VPos localPos =  getRowValignment();
        return null == localPos ? VPos.CENTER : localPos;
    }

    private class UnknowTypeException extends RuntimeException {
        private static final long serialVersionUID = 1L;
        public UnknowTypeException(String message) {
            super(message);
        }
    }

    private class NotFoundException extends RuntimeException {
        private static final long serialVersionUID = 1L;
        public NotFoundException(String message) {
            super(message);
        }
    }

}
于 2018-04-12T04:13:18.370 回答