如何使用setLayout(null)和背景图像将JPanel绝对定位在另一个JPanel上?

时间:2012-06-07 10:22:43

标签: java swing jpanel layout-manager absolutelayout

我正在使用Java中的JFrames,特别是需要重叠的绝对定位元素。我了解要覆盖组件,应该制作一个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);

...小孩,但不必要。

基本上,我想知道如何在具有背景图像的JPanel上绝对定位JPanels(或JComponents,如果这更简单)。

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

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

2 个答案:

答案 0 :(得分:3)

您在setLayout(null)上设置了JFrame,但未在“backgroundpanel”上设置{默认设置为FlowLayout)。

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

答案 1 :(得分:3)

希望找到最有可能在我面前的简单解决方案!

这样的东西?

LoginPanel

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