当我尝试通过按钮从另一个类访问 GUI 时,只会弹出一个标题栏

问题描述

我是一个新手程序员,我现在有点被这个问题困住了 2 个小时。所以我的问题是,每当我单击“注册”按钮时,屏幕左上角只会弹出一个标题栏(根本没有内容)。我怎样才能解决这个问题?提前致谢

btnRegister = new JButton("Register");
btnRegister.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
AccountCreationGUI window = new AccountCreationGUI();
window.setVisible(true);
frame.dispose();
                
            }
        });
btnRegister.setBounds(199,170,89,23);
frame.getContentPane().add(btnRegister);

AccountCreationGUI(我没有添加其他方法来缩短这个时间)

package main;
import java.sql.*;

import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.jpasswordfield;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JPanel;
import java.awt.Window.Type;

public class AccountCreationGUI extends JFrame {

    private JFrame frmToolInventory;
    private JTextField textfield_firstname;
    private JTextField textfield_lastname;
    private JTextField textfield_age;
    private JTextField textfield_username;
    private jpasswordfield passwordField;
    private jpasswordfield passwordField_1;
    JFrame frame;
    Connection connection = null;
    
    
    public static void main(String[] args) {
        EventQueue.invokelater(new Runnable() {
            public void run() {
                try {
                    AccountCreationGUI window = new AccountCreationGUI();
                    window.frmToolInventory.setVisible(true);
                } catch (Exception e) {
                    e.printstacktrace();
                }
            }
        });
    }

    
    public AccountCreationGUI() {
        initialize();
    }

public void initialize() {
        frmToolInventory = new JFrame();
        frmToolInventory.setResizable(false);
        frmToolInventory.setTitle("Tool Inventory");
        frmToolInventory.getContentPane().setBackground(new Color(0,51,51));
        frmToolInventory.setBounds(100,100,534,346);
        frmToolInventory.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
        frmToolInventory.getContentPane().setLayout(null);
        
        JLabel label_firstname = new JLabel("First Name");
        label_firstname.setForeground(new Color(255,255,255));
        label_firstname.setBounds(88,67,68,14);
        frmToolInventory.getContentPane().add(label_firstname);
        
        JLabel label_lastname = new JLabel("Last Name");
        label_lastname.setForeground(Color.WHITE);
        label_lastname.setBounds(88,92,14);
        frmToolInventory.getContentPane().add(label_lastname);
        
        JLabel label_username = new JLabel("Username");
        label_username.setForeground(Color.WHITE);
        label_username.setBounds(88,142,14);
        frmToolInventory.getContentPane().add(label_username);
        
        JLabel label_password = new JLabel("Password");
        label_password.setForeground(Color.WHITE);
        label_password.setBounds(88,167,14);
        frmToolInventory.getContentPane().add(label_password);
        
        JLabel label_reconfirmpassword = new JLabel("Re-confirm Password");
        label_reconfirmpassword.setForeground(Color.WHITE);
        label_reconfirmpassword.setBounds(88,192,101,14);
        frmToolInventory.getContentPane().add(label_reconfirmpassword);
        
        JLabel label_age = new JLabel("Age");
        label_age.setForeground(Color.WHITE);
        label_age.setBounds(88,117,14);
        frmToolInventory.getContentPane().add(label_age);
        
        textfield_firstname = new JTextField();
        textfield_firstname.setBounds(224,64,144,20);
        frmToolInventory.getContentPane().add(textfield_firstname);
        textfield_firstname.setColumns(10);
        
        textfield_lastname = new JTextField();
        textfield_lastname.setColumns(10);
        textfield_lastname.setBounds(224,20);
        frmToolInventory.getContentPane().add(textfield_lastname);
        
        textfield_age = new JTextField();
        textfield_age.setColumns(10);
        textfield_age.setBounds(224,114,20);
        frmToolInventory.getContentPane().add(textfield_age);
        
        textfield_username = new JTextField();      
        textfield_username.setColumns(10);
        textfield_username.setBounds(224,139,20);
        frmToolInventory.getContentPane().add(textfield_username);
        
        passwordField = new jpasswordfield();
        passwordField.setBounds(224,164,20);
        frmToolInventory.getContentPane().add(passwordField);
        
        passwordField_1 = new jpasswordfield();
        passwordField_1.setBounds(224,189,20);
        frmToolInventory.getContentPane().add(passwordField_1);
        
        JButton button_CreateAccount = new JButton("Create");
        button_CreateAccount.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                createAccount();    
            }
        });
        button_CreateAccount.setBounds(224,220,23);
        frmToolInventory.getContentPane().add(button_CreateAccount);
        
        JButton btnClear = new JButton("Clear");
        btnClear.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                clear();
            }
        });
        btnClear.setBounds(302,23);
        frmToolInventory.getContentPane().add(btnClear);
    }
    }
    

解决方法

我们可以对您的代码进行多项改进:

  1. setBounds(...).setLayout(null) 是您最大的敌人,Swing 必须处理不同的操作系统、PLAF、屏幕尺寸和分辨率,请参阅:Why is it frowned upon to use a null layout in Swing? 了解更多信息。当您在与您的计算机不同的计算机上展示您的 UI 时,像素完美的应用程序是一场噩梦,以下是如果您不遵循此建议的example 外观。了解不同的 Layout Managers 并使用它们,如果需要,您也可以将它们组合起来。

  2. 了解如何正确缩进您的代码,为此使用您的 IDE,谷歌类似 [Your IDE (IntelliJ / Eclipse / Netbeans / etc)] format code 并按照步骤操作,尝试记住命令,以便您的代码始终可供任何人阅读。

  3. textfield_firstname,不要使用 snake_case 来命名变量,在 Java 中 naming conventioncamelCase

    • FirstWordUpperCasedClass
    • firstWordLowerCasedVariable
    • firstWordLowerCasedMethod
    • ALL_WORDS_UPPER_CASED_CONSTANT
  4. 使用多个 JFrames 会造成糟糕的用户体验,因为每个 JFrame 实例都会在任务栏中创建自己的窗口,并且不会阻止您与其他框架进行交互,从而造成混乱对用户以及打开多个不同大小的窗口并不是一个好的体验 IMO。有关更深入的解释,请参阅 The Use of Multiple JFrames: Good or Bad Practice?(差)。

  5. 您的问题是,在 AccountCreationGUI 中,您无缘无故地扩展了 JFrame(我们称此 JFrameframe1),然后您创建了一个JFrame 的实例在这里:JFrame frmToolInventory; 然后另一个 JFrame frame;,所以你有 3 个 JFrames(看到这里的混淆部分?你必须跟踪所有不同的JFrames),您将所有组件添加到 frmTollInventory 但您使 frame1 可见:

    AccountCreationGUI window = new AccountCreationGUI();
    window.setVisible(true);
    frame.dispose();
    

对于这种特殊情况,您不需要调用 extends JFrame,这里有一个简单的程序,您可以稍后将其用作程序的基础:

import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MultiWindowGUI {
    private JFrame frame;
    private JPanel pane;
    private JButton dialogGUIButton;
    private JButton multipleJFrameButton;
    private ActionListener listener;
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MultiWindowGUI()::createAndShowGUI);
    }
    
    private void createAndShowGUI() {
        frame = new JFrame(getClass().getSimpleName());
        pane = new JPanel();
        dialogGUIButton = new JButton("Dialog (recommended)");
        multipleJFrameButton = new JButton("JFrame (not recommended)");
        
        listener = e -> {
            if (e.getSource().equals(dialogGUIButton)) {
                openDialogGUI();
            } else if (e.getSource().equals(multipleJFrameButton)) {
                openJFrameGUI();
            }
        };
        
        dialogGUIButton.addActionListener(listener);
        multipleJFrameButton.addActionListener(listener);
        
        pane.add(dialogGUIButton);
        pane.add(multipleJFrameButton);
        
        frame.add(pane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
    
    private void openDialogGUI() {
        JOptionPane.showMessageDialog(frame,new DialogGUI());
    }
    
    private void openJFrameGUI() {
        new MultiFrameGUI();
    }
}

class DialogGUI extends JPanel {
    private JLabel label;
    
    public DialogGUI() {
        label = new JLabel("A label inside a dialog window");
        
        add(label);
    }
}

class MultiFrameGUI {
    private JFrame frame;
    private JLabel label;
    
    public MultiFrameGUI() {
        frame = new JFrame(getClass().getSimpleName());
        label = new JLabel("A label inside a JFrame window");
        
        frame.add(label);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

我建议您在第二个按钮上单击 3-5 次,然后切换到另一个窗口,然后尝试找出您上次使用的是哪个 JFrame。看看如果您按下第一个按钮并返回到您的 JFrame 时切换到另一个窗口会发生什么?看到区别了吗?

另一种切换视图的方法是使用 CardLayout,这里有一个关于如何使用它的 example

,

对于位置,你需要指定一个位置;或者您可以使用系统默认值:

window.setLocationByPlatform(true);

https://stackoverflow.com/a/7778050/145976

至于尺寸,您需要设置一个尺寸,假设您使用的是布局管理器,请打包。

window.setPreferredSize(new Dimension(400,300));
window.pack();
,

我认为您创建的按钮很好,请查看 AccountCreationGUI 也许是您的问题。