带有LayoutManager的JLayeredPane [英] JLayeredPane with a LayoutManager

查看:75
本文介绍了带有LayoutManager的JLayeredPane的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:像在纸牌游戏中一样,画一堆纸牌.堆得很好.

The situation: drawing a stack of playing cards, like in the Solitaire game. Nicely stacked.

为实现这一点,我将JLayeredPaneLayoutManager接口的自定义实现结合使用.使用自定义LayoutManager的原因是堆栈方向各不相同,有时纸牌彼此完全覆盖,有时彼此覆盖,有时这种逻辑对于LayoutManager似乎是一件好事,因为这基本上可以归结为设置布局位置.卡.

To achieve this, I'm using a JLayeredPane in combination with a custom implementation of the LayoutManager interface. The reason for using a custom LayoutManager is that the stack orientation varies, sometimes the playing cards cover each other completely, sometimes partially, and this logic seems to be a good job for a LayoutManager, because this basically boils down to setting the location of the cards.

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

So, the LayoutManager is responsible for setting the X- and Y-coordinates of all components in my stack. The JLayeredPane on the other hand is responsible for their Z-coordinates (via its layers).

将组件添加到JLayeredPane就像这样:

Adding a component to a JLayeredPane goes like this:

JLayeredPane pane = new JLayeredPane();
pane.setLayout(new StackLayout(...));
pane.add(new CardView(...), new Integer(j));

其中,new Integer(j)是卡的层.由于JLayeredPane的约定,必须为Integer.

where new Integer(j) is the layer of the card. This must be an Integer due to the contract of JLayeredPane.

这里的问题是,由于上述原因,我的StackLayoutInteger外不能具有任何其他约束对象. LayoutManager界面要求您实现以下方法:

The problem here is, that my StackLayout cannot have any other constraint object than an Integer, due to the reason stated above. The LayoutManager interface requires you to implement the following method:

addLayoutComponent(Component comp, Object constraints);

和传递的Object在这里始终是Integer.

and the passed Object will here always be an Integer.

在我的特殊情况下,我很幸运,因为我的XY坐标可以基于Z坐标进行计算.例如,图层k中的卡片必须位于Y坐标k * offset处.因此,在我的情况下,约束对象为Integer没问题.

In my particular situation, I am lucky, as my XY-coordinates can be calculated based on the Z-coordinates. For example, the card in layer k has to be located at Y-coordinate k * offset. So in my situation, the constraints object being an Integer is not a problem.

我想知道Z坐标和XY坐标之间没有相关性时应该怎么做?那你怎么解决呢?例如,如何将GridBagLayoutJLayeredPane结合使用,其中第一个需要一个GridBagConstraints对象,第二个需要一个Integer对象?当然,GBL的布局方式不会使组件重叠,但这仅是想法.

I was wondering what you should be doing when there is no correlation between the Z-coordinates and the XY-coordinates? How can you solve this then? For example, how would I use a GridBagLayout in combination with a JLayeredPane, where the first requires a GridBagConstraints object and the second an Integer object? Of course, a GBL will layout in such a way that components do not overlap, but it's just the idea.

推荐答案

基于Hovercraft Full Of Eels的评论,我将回答我自己的问题.

Based on the comment of Hovercraft Full Of Eels, I'll answer my own question.

呼叫JLayeredPane.add(Component comp, Object constraints)将呼叫addImpl(Component comp, Object constraints, int index). JLayeredPane本身会覆盖此方法,这是源代码:

Calling JLayeredPane.add(Component comp, Object constraints) will call addImpl(Component comp, Object constraints, int index). This method is overridden by JLayeredPane itself, here's the source:

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(整数)传递给超级实现.超级实现中的重要部分Container是:

As you can see, the Integer object is intercepted, so that the JLayeredPane knows the layer in which comp should be placed. Then, it passes on constraints, the Integer, to the super implementation. The essential part in the super implementation, Container, is:

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的约束对象.

The solution would therefore be to extend JLayeredPane and override its addImpl(Component comp, Object constraints, int index) method, which can accept any Object of your choice: this object should contain the Integer needed for the JLayeredPane's layer decision, and it should also contain the constraints object for the chosen LayoutManager.

StackConstraints:

StackConstraints:

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扩展名:

JLayeredPane extension:

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();

}

这篇关于带有LayoutManager的JLayeredPane的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆