代码之家  ›  专栏  ›  技术社区  ›  darkchampionz

Java-顶部的GridBagLayout组件在调整大小时消失

  •  0
  • darkchampionz  · 技术社区  · 9 年前

    我使用 JLabel 在它的前面 JTextField 这样我就可以用一个值来表示一个类似防御的属性。我使用以下代码:

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10);
    
        JLabel jl = new JLabel();
        ImageIcon ii = new ImageIcon("C:\\Users\\Max\\Desktop\\shield.png");
        jl.setIcon(ii);
        gbc.gridy = 0;
        gbc.gridx = 0;
        add(jl, gbc);
    
        gbc.insets = new Insets(5, 10, 10, 10);
        JTextField jtf = new JTextField(2);
        jtf.setHorizontalAlignment(JTextField.CENTER);
        gbc.ipadx = 10;
        gbc.ipady = 10;
        gbc.gridy = 0;
        gbc.gridx = 0;
        jtf.setFocusable(false);
        add(jtf, gbc);
    

    并获得: enter image description here

    但是,如果我尝试调整窗口大小 文本框 永远消失,只有 标签类 显示。为什么会这样?

    1 回复  |  直到 9 年前
        1
  •  2
  •   MadProgrammer    9 年前
    1. 标签的位置和文本字段的位置之间没有关系,这意味着标签和字段可以彼此独立地自由移动
    2. 有一个z排序问题,容器顺序中较低的组件在容器顺序中较高的组件之后绘制(相反的顺序),这意味着当整个容器更新时,标签实际上是在屏蔽之前绘制的。它有时可能起作用的原因是,组件实际上可以彼此独立地绘制,这意味着文本字段实际上可以在不需要通知父容器或标签的情况下绘制

    例如

    Shield

    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
    
                gbc.insets = new Insets(5, 10, 10, 10);
                JTextField jtf = new JTextField(2);
                jtf.setHorizontalAlignment(JTextField.CENTER);
                gbc.ipadx = 10;
                gbc.ipady = 10;
                gbc.gridy = 0;
                gbc.gridx = 0;
                jtf.setFocusable(false);
                add(jtf, gbc);
    
                gbc = new GridBagConstraints();
                try {
                    JLabel jl = new JLabel();
                    ImageIcon ii = new ImageIcon(ImageIO.read(getClass().getResource("/shield01.png")));
                    jl.setIcon(ii);
                    gbc.gridy = 0;
                    gbc.gridx = 0;
                    add(jl, gbc);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
    
        }
    
    }
    

    一个可能更好的解决方案是创建一个“背景”组件,该组件获取图像并将其绘制为组件的背景,然后将文本字段添加到其中。

    Background

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.border.EmptyBorder;
    
    public class TestBackground {
    
        public static void main(String[] args) {
            new TestBackground();
        }
    
        public TestBackground() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new BorderLayout());
    
                try {
                    BackgroundPane pane = new BackgroundPane(ImageIO.read(getClass().getResource("/shield02.png")));
                    pane.setLayout(new GridBagLayout());
                    pane.setBorder(new EmptyBorder(5, 5, 5, 5));
                    GridBagConstraints gbc = new GridBagConstraints();
    
                    JTextField jtf = new JTextField(2);
                    jtf.setHorizontalAlignment(JTextField.CENTER);
                    gbc.ipadx = 10;
                    gbc.ipady = 10;
                    gbc.gridy = 0;
                    gbc.gridx = 0;
                    jtf.setFocusable(false);
                    pane.add(jtf, gbc);
    
                    add(pane);
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
            }
    
        }
    
        public class BackgroundPane extends JPanel {
    
            private BufferedImage img;
    
            public BackgroundPane(BufferedImage img) {
                this.img = img;
            }
    
            @Override
            public Dimension getPreferredSize() {
                return img != null ? new Dimension(img.getWidth(), img.getHeight()) : super.getPreferredSize();
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (img != null) {
                    int x = (getWidth() - img.getWidth()) / 2;
                    int y = (getHeight() - img.getHeight()) / 2;
                    g.drawImage(img, x, y, this);
                }
            }
    
        }
    
    }