首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有JLayeredPane的LayoutManager

带有JLayeredPane的LayoutManager
EN

Stack Overflow用户
提问于 2013-08-20 12:19:27
回答 2查看 4.3K关注 0票数 5

情况:画一堆扑克牌,就像纸牌游戏中一样。堆叠得很好。

为了实现这一点,我将使用JLayeredPaneLayoutManager接口的自定义实现相结合。使用自定义LayoutManager的原因是堆栈方向不同,有时扑克牌完全覆盖,有时部分覆盖,这种逻辑对于LayoutManager来说似乎是一项很好的工作,因为这基本上可以归结为设置卡片的位置。

因此,LayoutManager负责设置堆栈中所有组件的X-和Y-坐标.另一方面,JLayeredPane负责其Z坐标(通过其层)。

JLayeredPane添加组件如下所示:

代码语言:javascript
复制
JLayeredPane pane = new JLayeredPane();
pane.setLayout(new StackLayout(...));
pane.add(new CardView(...), new Integer(j));

其中new Integer(j)是卡的层。这必须是Integer,因为JLayeredPane的合同。

这里的问题是,由于上述原因,我的StackLayout不能有除Integer之外的任何其他约束对象。LayoutManager接口要求您实现以下方法:

代码语言:javascript
复制
addLayoutComponent(Component comp, Object constraints);

通过的Object在这里将永远是一个Integer

在我的特殊情况下,我很幸运,因为我的XY坐标可以根据Z坐标来计算。例如,图层k中的卡必须位于Y坐标k * offset上.因此,在我的情况下,约束对象是一个Integer不是一个问题。

我在想,当Z坐标和XY坐标之间没有关联时,你应该做什么呢?那你怎么解决这个问题呢?例如,如何结合使用GridBagLayoutJLayeredPane,其中第一个需要GridBagConstraints对象,第二个需要Integer对象。当然,GBL会以这样的方式布局,使组件不重叠,但这只是一个想法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-20 14:37:00

根据“全是鳗鱼”的评论,我会回答我自己的问题。

打电话给JLayeredPane.add(Component comp, Object constraints)会给addImpl(Component comp, Object constraints, int index)打电话。此方法由JLayeredPane本身重写,如下所示:

代码语言:javascript
复制
protected void addImpl(Component comp, Object constraints, int index) {
    int layer;
    int pos;

    if(constraints instanceof Integer) {
        layer = ((Integer)constraints).intValue();
        setLayer(comp, layer);
    } else
        layer = getLayer(comp);

    pos = insertIndexForLayer(layer, index);
    super.addImpl(comp, constraints, pos);
    comp.validate();
    comp.repaint();
    validateOptimizedDrawing();
}

正如您所看到的,Integer对象被拦截,这样JLayeredPane就知道comp应该放置在哪一层。然后,它将constraints ( Integer )传递给超级实现。超级实现Container的基本部分是:

代码语言:javascript
复制
protected void addImpl(Component comp, Object constraints, int index) {
    ...
    if (layoutMgr != null) {
        if (layoutMgr instanceof LayoutManager2) {
           ((LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints);
        } else if (constraints instanceof String) {
           layoutMgr.addLayoutComponent((String)constraints, comp);
        }
    }
    ...
}

因此,解决方案是扩展JLayeredPane并重写它的addImpl(Component comp, Object constraints, int index)方法,该方法可以接受您选择的任何对象:该对象应该包含JLayeredPane层决策所需的Integer,并且它还应该包含所选LayoutManager的约束对象。

StackConstraints:

代码语言:javascript
复制
public final class StackConstraints {
    public final int layer;
    public final Object layoutConstraints;
    public StackConstraints (int layer, Object layoutConstraints){
        this.layer = layer;
        this.layoutConstraints = layoutConstraints;
    }
}

JLayeredPane扩展:

代码语言:javascript
复制
protected void addImpl(Component comp, Object constraints, int index) {
    int layer;
    int pos;
    Object constr;
     if(constraints instanceof StackConstraints) {
        layer = constraints.layer.intValue();
        constr = ((StackConstraints) constraints).layoutConstraints;
        setLayer(comp, layer);
    } else {
        layer = getLayer(comp);
        constr = constraints;
    }

    pos = insertIndexForLayer(layer, index);
    super.addImpl(comp, constraints, pos);
    comp.validate();
    comp.repaint();
    validateOptimizedDrawing();

}

票数 3
EN

Stack Overflow用户

发布于 2013-08-20 14:51:26

因此,LayoutManager负责设置堆栈中所有组件的X-和Y-坐标.另一方面,JLayeredPane负责其Z坐标(通过其层)。

您不需要为此使用分层窗格。一个面板也支持Z-Order.请查看重叠布局,它解释了更多关于这一点的内容,并可能做您需要的事情。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18334874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档