2

我正在使用 Java 中的 JFrame,特别是使用需要重叠的绝对定位元素。我知道要覆盖组件,应该制作一个 JPanel(使用setOpacity(false);),并使用setBounds(x,y,x2,y2);setPosition(x,y)&定位它setSize(x,y)。不幸的是,面板的行为就像 CSS 的inline-divs;它们只占用生产线上所需的空间,并且不堆叠。

这是我到目前为止的代码,但它似乎不像我想象的那样:

class Login extends JFrame {
    private JPanel         backgroundpanel;
    private JPanel         panel;
    private JPanel         panel2;
    private JTextField     usernameBox;
    private JPasswordField passwordBox;
    private JButton        button;
    private int            height = 319;
    private int            width  = 452;
    private ImageIcon      ii     = new ImageIcon("special-window-BG.png");
    private JLabel         image;

    public Login() {
        setLayout(null);
        setTitle("Login");
        setSize(width,height);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);

        buildPanel();

        add(backgroundpanel);
        setVisible(true);
    }

    private void buildPanel() {
        usernameBox = new JTextField(20);
        passwordBox = new JPasswordField(20);
        button = new JButton("Login");
        image = new JLabel(ii);

        backgroundpanel = new JPanel();
        panel = new JPanel();
        panel2 = new JPanel();

        backgroundpanel.add(panel);
        backgroundpanel.add(panel2);
        backgroundpanel.add(image);

        panel.setBackground(Color.red);
        panel.setBounds(0, 0, 10, 10);
        panel.setOpaque(false);

        panel2.setBackground(Color.blue);
        panel2.setBounds(0, 0, 10, 10);
        panel2.setOpaque(false);

        panel.add(passwordBox);
        panel2.add(button);

        backgroundpanel.setOpaque(false);
        backgroundpanel.isOptimizedDrawingEnabled();
        backgroundpanel.setBounds(0, 0, width, height);

... cot'd,但没有必要。

所以基本上,我想知道如何将 JPanel(或 JComponents,如果更简单的话)绝对定位在带有背景图像的 JPanel 上。

感谢您查看此问题,我在此方法上花费了太多时间;注释掉的代码通过我发布的内容扩展了近 500 行,所以我无处可去。下图显示了我正在尝试完成的粗略说明,我不确定我是否真的接近完成它,因为有时 JComponents 似乎消失了,就好像它们在背景图像后面一样,但是我想找到最有可能就在我眼前的简单解决方案!

http://i.stack.imgur.com/revz8.jpg

4

2 回答 2

4

我想找到最有可能就在我眼前的简单解决方案!

像这样的东西?

登录面板

import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class LoginPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    BufferedImage image;

    LoginPanel(BufferedImage image) {
        super(new GridBagLayout());

        this.image = image;

        JPanel controls = new JPanel(new BorderLayout(15,35));
        controls.setOpaque(false);
        controls.setBorder(new EmptyBorder(110,0,0,0));

        JPanel fields = new JPanel(new GridLayout(0,1,30,30));
        fields.setOpaque(false);
        controls.add(fields, BorderLayout.CENTER);
        fields.add(new JTextField(20));
        fields.add(new JPasswordField(20));

        JPanel button = new JPanel(new GridBagLayout());
        button.setOpaque(false);
        controls.add(button, BorderLayout.PAGE_END);
        button.add(new JButton("Log In"));

        Dimension prefSize = new Dimension(image.getWidth(),image.getHeight());
        setPreferredSize(prefSize);

        add(controls);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
    }

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://i.stack.imgur.com/revz8.jpg");
        final BufferedImage image = ImageIO.read(url); 
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                LoginPanel p = new LoginPanel(image);
                JOptionPane.showMessageDialog(null, p);
            }
        });
    }
}
于 2012-06-07T11:27:58.533 回答
3

您正在设置setLayout(null)您的JFrame但不是在“背景面板”(默认设置为FlowLayout)。

您不应该设置Login框架的布局 - 因为它默认设置为BorderLayout- 没关系(您希望“背景面板”增长以匹配父级)。而是setLayout(null)在您的JPanel“背景面板”上添加任意定位的面板。

于 2012-06-07T11:23:45.420 回答