Java GridBagLayout:行重叠

Java GridBagLayout:行重叠,java,swing,overlap,gridbaglayout,overlapping,Java,Swing,Overlap,Gridbaglayout,Overlapping,我有一个非常简单的JFrame。有三个主面板:顶部的横幅图像、左侧的按钮列表,以及用户将在其中输入登录信息以访问应用程序其余部分的主面板 我使用的是GridBagLayout,尽管大多数人都像躲避瘟疫一样避开它,但它对我来说非常简单,尽管它确实在混合中添加了许多代码行。然而,我遇到了这样一个奇怪的问题:第一行(横幅图像)与第二行(按钮和登录面板)重叠。我已经检查了一遍又一遍,在网络上到处寻找答案,但是我不知道我做错了什么 基本上,底层行作为一个整体垂直居中于JFrame,而不是第二个GridBa

我有一个非常简单的JFrame。有三个主面板:顶部的横幅图像、左侧的按钮列表,以及用户将在其中输入登录信息以访问应用程序其余部分的主面板

我使用的是GridBagLayout,尽管大多数人都像躲避瘟疫一样避开它,但它对我来说非常简单,尽管它确实在混合中添加了许多代码行。然而,我遇到了这样一个奇怪的问题:第一行(横幅图像)与第二行(按钮和登录面板)重叠。我已经检查了一遍又一遍,在网络上到处寻找答案,但是我不知道我做错了什么

基本上,底层行作为一个整体垂直居中于JFrame,而不是第二个GridBag行。不知何故,横幅板被画在上面,尽管事先被添加到屏幕上。我认为这可能与BannerPanel的工作方式有关,但我个人找不到解决办法

这就是它看起来的样子:

它应该是这样的:

这是我的密码:

public class LoginWindow extends JFrame implements ActionListener {
    final static String unlockCode = "unlock";
    ArrayList <User> userlist = new ArrayList <User> ();
    User user = null;

    // The visible parts of the window
    GridBagConstraints gridbag;
    JLabel inputLabel, errorLabel, lockedLabel, unlockLabel;
    JTextField usernameField, unlockField;
    JPasswordField passwordField;
    JPanel inputPanel, usernamePanel, passwordPanel, unlockPanel;

    public static void main(String[] args) {
        LoginWindow win = new LoginWindow ();
        win.userlist.add(new User ("username", "password", true));
    }

    public LoginWindow () {
        setTitle("Login");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setBackground(Color.GRAY);
        setSize(640, 480);
        setResizable(false);
        resetGridbag();

        // This is where I declare all the JLabels, JPanels, etc
        inputLabel = new JLabel ("Secure Login");
        inputLabel.setFont(new Font ("SansSerif", Font.BOLD, 24));
        inputLabel.setForeground(Color.WHITE);

        JLabel usernameLabel = new JLabel ("Username  ");
        usernameLabel.setForeground(Color.WHITE);
        usernameField = new JTextField (10);
        usernameField.setActionCommand("Login");
        usernameField.addActionListener(this);
        usernamePanel = new JPanel ();
        usernamePanel.setBackground(Color.GRAY);
        usernamePanel.add(usernameLabel);
        usernamePanel.add(usernameField);

        JLabel passwordLabel = new JLabel ("Password  ");
        passwordLabel.setForeground(Color.WHITE);
        passwordField = new JPasswordField (10);
        passwordField.setActionCommand("Login");
        passwordField.addActionListener(this);
        passwordPanel = new JPanel ();
        passwordPanel.setBackground(Color.GRAY);
        passwordPanel.add(passwordLabel);
        passwordPanel.add(passwordField);

        errorLabel = new JLabel ("");
        errorLabel.setForeground(Color.WHITE);

        lockedLabel = new JLabel ("You've been locked out!");
        lockedLabel.setForeground(Color.WHITE);

        unlockLabel = new JLabel ("Unlock Code");
        unlockLabel.setForeground(Color.WHITE);
        unlockField = new JTextField (10);
        unlockField.setActionCommand("Unlock");
        unlockField.addActionListener(this);
        unlockPanel = new JPanel ();
        unlockPanel.setBackground(Color.GRAY);
        unlockPanel.add(unlockLabel);
        unlockPanel.add(unlockField);

        JLabel newPassword = new JLabel ("Request a new password");
        newPassword.setForeground(Color.WHITE);
        JPanel optionPanel = new JPanel ();
        optionPanel.setBackground(Color.GRAY);
        optionPanel.add(newPassword);

        inputPanel = new JPanel ();
        inputPanel.setBackground(Color.GRAY);
        inputPanel.setLayout(new GridBagLayout ());

        // Now I'm going to add them all to the screen
        GridBagLayout gbl = new GridBagLayout ();
        gbl.columnWeights = new double [] {0.0f, 1.0f};
        gbl.rowWeights = new double [] {0.0f, 1.0f};
        setLayout(gbl);

        gridbag.gridwidth = 2;
        gridbag.gridy = 0;
        gridbag.fill = GridBagConstraints.HORIZONTAL;
        add(new BannerPanel (), gridbag);
        gridbag.gridy = 1;
        gridbag.gridwidth = 1;
        gridbag.anchor = GridBagConstraints.NORTHWEST;
        add(optionPanel, gridbag);
        gridbag.gridx++;
        gridbag.anchor = GridBagConstraints.CENTER;
        add(inputPanel, gridbag);

        redraw();
        setVisible(true);
    }

    public void resetGridbag () {
        gridbag = new GridBagConstraints ();
        gridbag.anchor = GridBagConstraints.CENTER;
        gridbag.gridx = gridbag.gridy = 0;
    }

    public void reset () {
        inputPanel.removeAll();
        resetGridbag();
        validate();
        repaint();
    }

    public void redraw () {
        reset();
        if (user == null || !user.locked()) {
            inputPanel.add(inputLabel, gridbag);
            gridbag.gridy++;
            inputPanel.add(new JLabel ("   "), gridbag);
            gridbag.gridy++;
            inputPanel.add(usernamePanel, gridbag);
            gridbag.gridy++;
            inputPanel.add(passwordPanel, gridbag);
            gridbag.gridy++;
            inputPanel.add(new JLabel ("   "), gridbag);
            gridbag.gridy++;
            inputPanel.add(errorLabel, gridbag);
        }
        else {
            inputPanel.add(lockedLabel, gridbag);
            gridbag.gridy++;
            inputPanel.add(unlockPanel, gridbag);
            gridbag.gridy++;
            inputPanel.add(errorLabel, gridbag);
            errorLabel.setText("");
        }
        validate();
        repaint();
    }

    public void actionPerformed (ActionEvent e) {
        String button = e.getActionCommand();
        if (button.equals("Login")) {
            boolean usernameMatch = false;
            boolean passwordMatch = false;

            for (int i = 0; i < userlist.size(); i++) {
                if (usernameField.getText().equals(userlist.get(i).username())) {
                    usernameMatch = true;
                    user = userlist.get(i);
                }
                if (new String (passwordField.getPassword()).equals(userlist.get(i).password()))
                    passwordMatch = true;
            }
            passwordField.setText("");

            if (usernameMatch) {
                if (passwordMatch) {
                    user.unlock();
                    //new MainWindow ();
                    dispose();
                }
                else {
                    user.loginFail();
                    if (!user.locked())
                        errorLabel.setText("Login unsuccessful. " +
                                user.loginAttempts() + " attempts left!");
                    else
                        redraw();
                }
            }
            else
                errorLabel.setText("Login unsuccessful.");

            validate();
        }
        else if (button.equals("Unlock")) {
            if (unlockField.getText().equals(unlockCode)) {
                errorLabel.setText("");
                user.unlock();
                redraw();
            }
            else {
                errorLabel.setText("Invalid unlock code.");
                validate();
            }
            unlockField.setText("");
        }
    }
}

class BannerPanel extends JPanel {
    Image image;
    int width = 0, height = 0;
    double ratio = 0.0;

    public BannerPanel () {
        try {
            image = ImageIO.read(BannerPanel.class
                    .getClassLoader().getResourceAsStream("banner.png"));
        }
        catch (Exception e) { e.printStackTrace(); }
    }

    @Override
    protected void paintComponent (Graphics g) {
        super.paintComponent(g);

        ratio = (double) getWidth() / image.getWidth(null);
        width = getWidth();
        height = getImageHeight();
        setSize(width, height);

        if (image != null) {
            g.drawImage(image, 0, 0, width, height, this);
        }
    }

    public int getImageHeight () {
        return (int) (image.getHeight(null) * ratio);
    }
}

public class User {
    String username = "";
    String password = "";
    boolean superuser = false;
    int loginAttempts = 3;

    public User (String username, String password, boolean superuser) {
        this.username = username;
        this.password = password;
        this.superuser = superuser;
    }

    public String username () {
        return username;
    }

    public String password () {
        return password;
    }

    public boolean superuser () {
        return superuser;
    }

    public int loginAttempts () {
        return loginAttempts;
    }

    public void loginFail () {
            if (loginAttempts > 0)
            loginAttempts--;
    }

    public boolean locked () {
        return (loginAttempts == 0);
    }

    public void lock () {
        loginAttempts = 0;
    }

    public void unlock () {
        loginAttempts = 3;
    }
}
公共类LoginWindow扩展JFrame实现ActionListener{
最终静态字符串unlockCode=“unlock”;
ArrayList userlist=新的ArrayList();
User=null;
//窗口的可见部分
gridbag约束gridbag;
JLabel inputLabel、errorLabel、lockedLabel、unlockLabel;
JTextField usernameField,unlockField;
JPasswordField密码域;
JPanel输入面板、用户名面板、密码面板、解锁面板;
公共静态void main(字符串[]args){
LoginWindow=newloginwindow();
添加(新用户(“用户名”,“密码”,true));
}
公共登录窗口(){
设置标题(“登录”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(颜色为.GRAY);
设置大小(640480);
可设置大小(假);
resetGridbag();
//这是我声明所有jlabel、jpanel等的地方
inputLabel=新的JLabel(“安全登录”);
inputLabel.setFont(新字体(“SansSerif”,Font.BOLD,24));
inputLabel.setForeground(颜色:白色);
JLabel usernamelab=新的JLabel(“用户名”);
usernamelab.setForeground(颜色:白色);
usernameField=newjtextfield(10);
usernameField.setActionCommand(“登录”);
usernameField.addActionListener(此);
usernamePanel=newjpanel();
usernamePanel.setBackground(颜色:灰色);
添加(usernamelab);
添加(usernameField);
JLabel passwordLabel=新的JLabel(“密码”);
passwordLabel.setForeground(颜色:白色);
passwordField=newjpasswordfield(10);
passwordField.setActionCommand(“登录”);
passwordField.addActionListener(此);
passwordPanel=newjpanel();
passwordPanel.setBackground(颜色:灰色);
passwordPanel.add(passwordLabel);
passwordPanel.add(passwordField);
errorLabel=新的JLabel(“”);
errorLabel.setForeground(颜色:白色);
lockedLabel=new JLabel(“你被锁在外面了!”);
锁定标签。设置前景(颜色。白色);
解锁标签=新的JLabel(“解锁代码”);
解锁标签。设置前景(颜色。白色);
unlockField=新的JTextField(10);
unlockField.setActionCommand(“Unlock”);
unlockField.addActionListener(此);
unlockPanel=newJPanel();
解锁面板。背景(颜色。灰色);
解锁面板。添加(解锁标签);
解锁面板。添加(解锁字段);
JLabel newPassword=新JLabel(“请求新密码”);
newPassword.setForeground(颜色:白色);
JPanel optionPanel=新的JPanel();
选项面板。立根背景(颜色。灰色);
选项面板。添加(新密码);
inputPanel=newJPanel();
输入面板。背景(颜色。灰色);
setLayout(新的GridBagLayout());
//现在我将把它们全部添加到屏幕上
GridBagLayout gbl=新的GridBagLayout();
gbl.columnWeights=新的双[]{0.0f,1.0f};
gbl.rowWeights=新的双[]{0.0f,1.0f};
设置布局(gbl);
gridbag.gridwidth=2;
gridbag.gridy=0;
gridbag.fill=GridBagConstraints.HORIZONTAL;
添加(新的BannerPanel(),gridbag);
gridbag.gridy=1;
gridbag.gridwidth=1;
gridbag.anchor=GridBagConstraints.NORTHWEST;
添加(选项面板、gridbag);
gridbag.gridx++;
gridbag.anchor=GridBagConstraints.CENTER;
添加(输入面板、网格包);
重画();
setVisible(真);
}
公共垃圾袋(){
gridbag=新的GridBagConstraints();
gridbag.anchor=GridBagConstraints.CENTER;
gridbag.gridx=gridbag.gridy=0;
}
公共无效重置(){
inputPanel.removeAll();
resetGridbag();
验证();
重新油漆();
}
公共无效重绘(){
重置();
if(user==null | |!user.locked()){
inputPanel.add(inputLabel,gridbag);
gridbag.gridy++;
inputPanel.add(新JLabel(“”),gridbag);
gridbag.gridy++;
添加(usernamePanel,gridbag);
gridbag.gridy++;
添加(密码面板,gridbag);
gridbag.gridy++;
inputPanel.add(新JLabel(“”),gridbag);
gridbag.gridy++;
inputPanel.add(错误标签、网格包);
}
否则{
输入面板。添加(锁定标签、网格袋);
gridbag.gridy++;
添加(解锁面板、网格包);
gridbag.gridy++;
inputPanel.add(错误标签、网格包);
errorLabel.setText(“”);
}
验证();
重新油漆();
}
已执行的公共无效诉讼(诉讼E)
@Override
public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x, y, width, height);
    int pWidth = getPreferredSize().width;
    setPreferredSize(new Dimension(pWidth, width / 2));
}
class BannerPanel extends JPanel {
    Image image;
    int width = 0, height = 0;
    double ratio = 0.0;

    public BannerPanel () {
        try {
            image = ImageIO.read(BannerPanel.class
                    .getClassLoader().getResourceAsStream("banner.png"));
        }
        catch (Exception e) { e.printStackTrace(); }
    }

    @Override
    protected void paintComponent (Graphics g) {
        super.paintComponent(g);

        ratio = (double) getWidth() / image.getWidth(null);
        width = getWidth();
        height = getImageHeight();
        setPreferredSize(new Dimension (width, height));
        setSize(width, height);

        if (image != null) {
            g.drawImage(image, 0, 0, width, height, this);
        }
    }

    public int getImageHeight () {
        return (int) (image.getHeight(null) * ratio);
    }
}