显式设置位置时出现MigLayout问题

时间:2013-10-07 20:17:05

标签: java swing user-interface miglayout

在显式设置组件的位置(使用id.x和id.y约束)并调整添加组件的容器大小时,我在MigLayout中遇到问题。这是一个SSCCE:

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.miginfocom.swing.*;

public class MigClass extends JFrame {

    MigClass(String title) {
        super(title);
        MigLayout layout = new MigLayout();
        setLayout(layout);
        final JPanel content = new JPanel(new MigLayout()); 

        final JLabel l1 = new JLabel("A label");
        content.add(l1, "push, center, top, id l1");
        l1.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                final JTextField editor = new JTextField(5);
                content.add(editor, "pos l1.x l1.y");
                editor.setVisible(true);
                l1.setVisible(false);
                editor.addKeyListener(new KeyListener() {
                    @Override
                    public void keyTyped(KeyEvent e) {
                    }

                    @Override
                    public void keyPressed(KeyEvent e) {
                        if(e.getKeyCode() == (KeyEvent.VK_ENTER)) {
                            l1.setText(editor.getText());
                            editor.setVisible(false);
                            l1.setVisible(true);
                        }
                    }

                    @Override
                    public void keyReleased(KeyEvent e) {
                    }                   
                });
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }

        });
        add(content, "grow, push, span");
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        MigClass gui = new MigClass(null);
    }
}

如果约束JTextField被添加到标签中,"push"编辑器没有正确的位置(它应该与l1的位置重叠)(仅当帧被放大时才会发生这种情况)。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

文档中没有明确说明,但您不能 将相对定位与网格结构混合。要么使用 相对定位或正常网格结构。

无需设置两个MigLayout经理。该 面板可以简单地添加到中心区域 BorderLayout

我想出了一个利用hidemode约束的解决方案。

package com.zetcode;

import java.awt.EventQueue;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;


public class MigLayoutReplaceEx extends JFrame {

    public MigLayoutReplaceEx() {

        initUI();

        setSize(300, 250);
        setTitle("Replace component");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private void initUI() {

        JPanel pnl = new JPanel(new MigLayout());

        JLabel lbl = new JLabel("A label");
        pnl.add(lbl, "cell 0 0, hidemode 3");        

        JTextField field = new JTextField(10);
        pnl.add(field, "cell 0 0, hidemode 3");
        field.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == (KeyEvent.VK_ENTER)) {

                    lbl.setText(field.getText());
                    field.setVisible(false);
                    lbl.setVisible(true);
                }
            }
        });

        field.setVisible(false);

        lbl.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                lbl.setVisible(false);
                field.setVisible(true);
            }
        });

        add(pnl);
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutReplaceEx ex = new MigLayoutReplaceEx();
                ex.setVisible(true);
            }
        });
    }
}

该示例在窗口上显示标签。点击标签我们隐藏标签 并显示文本字段。当我们在字段中按Enter键时,文本字段将被隐藏 并显示标签,从文本字段中复制新文本。

hidemode 3隐形组件中不参与布局。我们可以 因此动态显示组件在同一单元格中的其他组件 永远都是隐藏的。