Java GridBagLayout:行重叠
我有一个非常简单的JFrame。有三个主面板:顶部的横幅图像、左侧的按钮列表,以及用户将在其中输入登录信息以访问应用程序其余部分的主面板 我使用的是GridBagLayout,尽管大多数人都像躲避瘟疫一样避开它,但它对我来说非常简单,尽管它确实在混合中添加了许多代码行。然而,我遇到了这样一个奇怪的问题:第一行(横幅图像)与第二行(按钮和登录面板)重叠。我已经检查了一遍又一遍,在网络上到处寻找答案,但是我不知道我做错了什么 基本上,底层行作为一个整体垂直居中于JFrame,而不是第二个GridBag行。不知何故,横幅板被画在上面,尽管事先被添加到屏幕上。我认为这可能与BannerPanel的工作方式有关,但我个人找不到解决办法 这就是它看起来的样子: 它应该是这样的: 这是我的密码:Java GridBagLayout:行重叠,java,swing,overlap,gridbaglayout,overlapping,Java,Swing,Overlap,Gridbaglayout,Overlapping,我有一个非常简单的JFrame。有三个主面板:顶部的横幅图像、左侧的按钮列表,以及用户将在其中输入登录信息以访问应用程序其余部分的主面板 我使用的是GridBagLayout,尽管大多数人都像躲避瘟疫一样避开它,但它对我来说非常简单,尽管它确实在混合中添加了许多代码行。然而,我遇到了这样一个奇怪的问题:第一行(横幅图像)与第二行(按钮和登录面板)重叠。我已经检查了一遍又一遍,在网络上到处寻找答案,但是我不知道我做错了什么 基本上,底层行作为一个整体垂直居中于JFrame,而不是第二个GridBa
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);
}
}