本文介绍了java哪个布局管理器适合这个任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JPanel父级,里面有3个JPanel子级。他们目前都使用GridLayout并一起代表一个UML类。问题是,当我添加新属性或方法时,所有3个JPanel都会增长到相同的大小。

I have a JPanel parent with 3 JPanel children inside. They all currently make use of GridLayout and together represent a UML class. Problem is that when I add a new attribute or method, all 3 JPanel grow to the same size.

欲望行为是:


  1. 标题栏的大小始终保持不变每当添加方法或属性时。

  2. 添加方法时,只有方法面板增长,标题和属性面板的大小保持不变。

  3. 添加属性时,只有属性面板增长,其他面板大小保持不变。

父JPanel已经可以自动增长/只要添加方法/属性,缩小。我正在玩弄GridBagLayout atm,但我无法接近欲望的结果。

The parent JPanel already can automatically grow/shrink whenever a method/attribute is added. I'm toying around with GridBagLayout atm but I'm getting nowhere near the desire results.

我有一个简单(或更简单)的方法来解决这个问题吗?!

Is there a simple (or simpler) way for me to solve this?!

这里有几张照片可以显示我的情况。

Here is few pics to show my situation.

新创建的UML类=>
这是它当前的行为方式=>

A newly created UML class => this is how it currently behaves =>

但我希望这个=> 或者=> 或者=>

But I want this => or this=> or this =>

Edit2:为了清晰起见添加了新的图片。如果原始版本具有误导性,我非常抱歉。

added new pics for clarity. Im terribly sorry if original version was misleading.

Edit3:YESS!我已经整理好了!感觉就像永远!这是SSEEC:

YESS! I have sorted it! Felt like forever!! Here is the SSEEC:

子面板

    import java.awt.Component;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;

    public class APanel extends JPanel{
        private JTextField tf;

    public APanel() {
        this.setLayout(new GridLayout(0,1));
        this.addMouseListener(mouseInputListener);
      }

    MouseInputListener mouseInputListener = new MouseInputAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
        System.out.println("Adding a new text field!");
        tf = MyTF.create("Double click");
        addNewTF(tf);
        Component source = (Component) e.getSource();
        Container c = source.getParent();
        while(true) {
            if(c instanceof PPanel)
                break;
            else
                c=c.getParent();
        }
        PPanel p = (PPanel) c;
        p.expand();
        }
    };

    public void addNewTF(JTextField tf) {
        this.add(tf);
        this.setSize(this.getWidth(), this.getHeight()+tf.getHeight());
        this.revalidate();
        this.repaint();

    }
}

父面板:

    import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class PPanel extends JPanel{
    //private APanel panel1;
    private JPanel panel1;
    private APanel panel2;
    private APanel panel3;
    public PPanel() {

        this.setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
        this.setBackground(Color.black);

        panel1 = new JPanel();
        panel1.setLayout(new GridLayout(0,1));
        panel1.add(new JTextField("title"));
        panel2 = new APanel();
        panel2.setBorder(BorderFactory.createLineBorder(Color.red));
        panel3 = new APanel();
        panel3.setBorder(BorderFactory.createLineBorder(Color.black));

        this.add(panel1);
        this.add(Box.createRigidArea(new Dimension(0,1)));
        this.add(panel2);
        this.add(panel3);


    }
    public void expand() {
        this.setSize(this.getWidth(), this.getHeight()+33);
        this.revalidate();
        this.repaint();
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        PPanel panel = new PPanel();
        panel.setBounds(10, 10, 100, 150);
        JPanel c = new JPanel(null);
        c.add(panel);
        frame.add(c);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(350, 300));
        frame.setTitle("Demo");
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

帮助类:

    import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import javax.swing.JTextField;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;

public class MyTF {
    public static JTextField create(String name) {
        final JTextField tf = new JTextField(name);
        System.out.println(tf.getPreferredSize());
        tf.setPreferredSize(new Dimension(100,33));
        tf.addMouseListener(mouseInputListener);
        return tf;
    }

    static MouseInputListener mouseInputListener = new MouseInputAdapter() {
        @Override
            public void mouseClicked(MouseEvent e) {
                Component source = (Component) e.getSource();
                Container c = source.getParent();
                while(true) {
                    if(c instanceof PPanel)
                        break;
                    else if(c instanceof APanel)
                    {
                        c.dispatchEvent(e);
                        c = c.getParent();
                        break;

                    }
                    else
                        c=c.getParent();
                }
                c.dispatchEvent(e);
        }

    };
}

我放弃了使用GridBagLayout玩的efford,这对我来说太过分了。然后我按照建议尝试了borderLayout但是无法让它像我想要的那样工作。然后最后BoxLayout,它应该工作但我的代码中有一个错误!因此,当我尝试使用0verbose代码建议并使用它时,它失败了!直到我完成了SSEEC,最后编译并在我决定发布之前运行它(我此时几乎放弃了)然后我意识到它有效......可以在自己的空间中成长的面板,它们不要互相干扰。

I gave up the efford playing with GridBagLayout, it was just too much for me. Then I tried borderLayout as suggested but couldn't get it to work like I want it either. Then finally BoxLayout, it should had worked but there was a bug in my code! So when I tried out 0verbose code suggest and playing around with it, it failed! Not until, I finished up the SSEEC, did the final compile and run it before I decided to post (I practically gave up at this point) then I realised that it worked...The panel that can grow in their own space, they dont interfere with each other.

我就像WTF!

回到我的代码并比较它SSEEC并且有一个bug,扩展面板高度的代码在错误的地方所以他们有点喜欢吃彼此空间。

Went back to my code and compared it SSEEC and there was a bug, the code to expand the height of the panel was in wrong place so they sort of like eating into each other spaces.

更好!我可以指定中间框与其上方和下方的框之间的距离为一个像素。这意味着我仍然可以使用mKorbel的技巧来绘制背线来分隔这些框!

Better yet! I can specify the distance between the middle box with the box above and below it by one pixel. That means I can still use the trick by mKorbel to draw the back line seperating those boxes!

编辑4:有没有办法让我设置一个组件的大小?如果您运行SSEEC,您会注意到一旦添加了JTextField,它就是巨大的!它比容器大......

Edit 4: is there a way for me to set size of a component? If you run the SSEEC, you will notice that once the JTextField is added in, it's huge! It's bigger than the container...

推荐答案

我建议你使用BoxLayout。这是一个。使用胶水和刚性区域,您可以获得几乎所有所需的布局。在你的情况下,代码应该是这样的:

I suggest you to use BoxLayout. Here's a tutorial. Playing around with glues and rigid area you can obtain almost all desired layout. In your case the code should be somthing like this:

JPanel container = new JPanel();
container .setLayout(new BoxLayout(container , BoxLayout.Y_AXIS));

JPanel childTop = new JPanel();
JPanel childCenter = new JPanel();
JPanel childBottom = new JPanel();


childTop.setMaximumSize(...);
childBottom.setMaximumSize(...);

container.add(childTop);
container.add(Box.createVerticalGlue());
container.add(childCenter);
container.add(Box.createVerticalGlue());
container.add(childBottom);

当你需要插入一个新孩子时,记得把它插入正确的位置:胶水和儿童中心。
例如:

When you need to insert a new child, remember to insert it into the right position: between one of the glues and childCenter.For example:

container.add(newChild, 2) ;

这篇关于java哪个布局管理器适合这个任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-17 17:19
查看更多