Java 帧处理会创建额外的空帧

标签 java swing jframe dispose

我正在制作一个简单的登录应用程序,但是每次我按下按钮打开另一个框架(来自另一个类)时,由于某种原因,我都会得到一个额外的空框架。 我尝试通过编写一个新类并将其连接到另一个按钮来测试它..该类只有 JFrame..它仍然会给我另一个空框架。

代码

package application;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
/**
 *
 * @author 
 */
public class MainScreen extends JFrame{
    private JFrame frame;// frame of the interface
    private JPanel panel = new JPanel();
    private JPanel left = new JPanel();
    private JPanel center = new JPanel();
    private JPanel top = new JPanel();
    private JButton approve = new JButton("Approve");
    private JButton review = new JButton("Review");
    private JButton employmentCreate = new JButton("Create/Modify");
    private JLabel PR = new JLabel("Personal Records");
    private JLabel ER = new JLabel("Employment Records");
    private JLabel PerR = new JLabel("Perform Review");
    private JLabel AR = new JLabel("Approve Records");
    private JLabel news = new JLabel("There are no news");
    private JLabel empty = new JLabel();
    private JButton logout = new JButton("Logout");
    private JButton personalCreate = new JButton("Create/Modify");
    private JLabel welcome = new JLabel("Welcome:");
    private JLabel userLbl = new JLabel("USERNAME GOES HERE");

    public MainScreen()
    {
        makeFrame();
    }
    private void makeFrame()
    {
       frame = new JFrame("Main Screen");  
       frame.setSize(650,550);
       frame.setResizable(false);
       makeMenuBar(frame);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       Container contentPane = frame.getContentPane();
       //makes application start in the center of the screen
       Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
       frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
       //border
       UIManager.getDefaults().put("TitledBorder.titleColor", Color.BLACK);
       Border lowerEtched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
       TitledBorder title = BorderFactory.createTitledBorder(lowerEtched, "Main Screen");
       Font titleFont = UIManager.getFont("TitledBorder.font");
       title.setTitleFont( titleFont.deriveFont(Font.ITALIC + Font.BOLD) );
       panel.setBorder( title );
       //border end
       frame.setVisible(true);  
       frame.add(panel);
       panel.setLayout(new BorderLayout());
       panel.add(top, BorderLayout.PAGE_START);
       top.add(welcome);
       top.add(userLbl);
       panel.add(left, BorderLayout.LINE_START);
       left.add(news);
       panel.add(center, BorderLayout.CENTER);
       left.setPreferredSize(new Dimension(200,150));
       center.setLayout( new GridLayout(5,2));
       center.add(PR);
       center.add(personalCreate);
       personalCreate.addActionListener(new ActionListener()
        {public void actionPerformed(ActionEvent e) 
        {
            frame.dispose();
            PR pr = new PR();
            pr.setVisible(true);
        }
         });
       center.add(ER);
       center.add(employmentCreate);
       employmentCreate.addActionListener(new ActionListener()
        {public void actionPerformed(ActionEvent e) 
        {
            frame.dispose();
            ER er = new ER();
            er.setVisible(true);
        }
         });
       center.add(PerR);
       center.add(review);
       center.add(AR);      
       center.add(approve);
       center.add(empty);
       center.add(logout);

       //border
       UIManager.getDefaults().put("TitledBorder.titleColor", Color.BLACK);
       TitledBorder title2 = BorderFactory.createTitledBorder(lowerEtched, "News");
       Font title2Font = UIManager.getFont("TitledBorder.font");
       title.setTitleFont( titleFont.deriveFont(Font.ITALIC + Font.BOLD) );
       left.setBorder( title2 );
       //border end



    }
     /**
     * Receive notification of an action.
     */
    public void actionPerformed(ActionEvent event) 
    { 
        System.out.println("Menu item: " + event.getActionCommand());
    } 

    /**
     * Quits the application.
     */
    private void quit()
    {
        System.exit(0);
    }
       /**
     * About pop up.
     */
    private void about()
    {
        JOptionPane.showMessageDialog(frame, 
                    "Group Project Application",
                    "About Application",
                    JOptionPane.INFORMATION_MESSAGE);
    }
    /**
     * Restarts the application
     */
    private void restart()
    {
       frame.dispose();
        makeFrame();
    }
      /**
     * Creates the main frame's menu bar with menu items.
     */
    private void makeMenuBar(JFrame frame)
    {
        JMenuBar menubar = new JMenuBar();
        frame.setJMenuBar(menubar);
        JMenu menu;
        JMenuItem item;

        // create's File menu
        menu = new JMenu("File");
        menubar.add(menu);
        //restart application
        item = new JMenuItem("Restart");
        item.addActionListener(new ActionListener()
        {public void actionPerformed(ActionEvent e) { restart(); }
         });
        menu.add(item);
        //quit button
        item = new JMenuItem("Quit");
        item.addActionListener(new ActionListener()
        {public void actionPerformed(ActionEvent e) { quit(); }
         });
        menu.add(item);       

        //create's About menu
        menu= new JMenu ("Help");
        menubar.add(menu);

        item = new JMenuItem("About");
        item.addActionListener(new ActionListener() 
        { public void actionPerformed(ActionEvent e) { about(); }
        });
        menu.add(item);

    }

}

最佳答案

MainScreen 不必要地扩展了 JFrame。因此,当您创建 MainStream 对象时,您将创建并显示两个 JFrame,一个 MainStream 对象,另一个是由 MainStream 对象创建的。但更重要的是,您的类太复杂并且不独立,因此很难单独测试它们。考虑使用 SOLID 重新编码设计原则。这将使您的代码更容易调试和增强。

<小时/>

改变

  login.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {

        // .... etc...

        JOptionPane.showMessageDialog(null, "Welcome");
        frame.dispose();

        MainScreen s = new MainScreen();
        s.setVisible(true);
     }

  login.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {

        // .... etc...

        JOptionPane.showMessageDialog(null, "Welcome");
        frame.dispose();

        MainScreen s = new MainScreen();
        // !!  s.setVisible(true);  // don't call this!
     }

并且不要让 MainScreen 扩展 JFrame。

您的代码还存在很多其他问题,但这是导致当前错误的原因。

其他问题:

  • 忽略异常。阅读异常教程,这样您就不会盲目行事。
  • 将数据库代码与 GUI 代码混合。尝试将它们放在单独的可测试单元中。
  • 不必要地扩展 JFrame。您几乎不需要或不想这样做。
  • 交换 JFrame,您应该在大部分情况下显示单个稳定的 JFrame,并交换 JPanel View 。
  • 在向 JFrame 添加所有组件之前在 JFrame 上调用 setVisible(true)。这可能会导致创建空 JFrame。添加组件之后始终调用 setVisible(true)。
<小时/>

简化的测试程序以表明我的建议有效:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Application {
   public static void main(String[] args) {
      new Login();
   }
}

class Login {
   private JFrame frame;// frame of the interface
   private JButton login = new JButton("Login");
   private JPanel panel = new JPanel();

   public Login() {
      makeFrame();
   }

   private void makeFrame() {
      frame = new JFrame("Login");
      frame.setSize(300, 200);
      // !! frame.setVisible(true);
      frame.add(panel);
      panel.add(login);
      login.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(null, "Welcome");
            frame.dispose();
            MainScreen s = new MainScreen();
            // s.setVisible(true); // !! get rid of
         }
      });
      frame.setVisible(true);
   }
}

class MainScreen {
   private JFrame frame;// frame of the interface
   private JPanel panel = new JPanel();
   private JPanel left = new JPanel();
   private JPanel center = new JPanel();
   private JPanel top = new JPanel();
   private JButton approve = new JButton("Approve");
   private JButton review = new JButton("Review");
   private JButton employmentCreate = new JButton("Create/Modify");
   private JLabel PR = new JLabel("Personal Records");
   private JLabel ER = new JLabel("Employment Records");
   private JLabel PerR = new JLabel("Perform Review");
   private JLabel AR = new JLabel("Approve Records");
   private JLabel news = new JLabel("There are no news");
   private JLabel empty = new JLabel();
   private JButton logout = new JButton("Logout");
   private JButton personalCreate = new JButton("Create/Modify");
   private JLabel welcome = new JLabel("Welcome:");
   private JLabel userLbl = new JLabel("USERNAME GOES HERE");

   public MainScreen() {
      makeFrame();
   }

   private void makeFrame() {
      frame = new JFrame("Main Screen");
      frame.setSize(650, 550);
      frame.setResizable(false);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      // frame.setVisible(true);
      frame.add(panel);
      panel.setLayout(new BorderLayout());
      panel.add(top, BorderLayout.PAGE_START);
      top.add(welcome);
      top.add(userLbl);
      panel.add(left, BorderLayout.LINE_START);
      left.add(news);
      panel.add(center, BorderLayout.CENTER);
      left.setPreferredSize(new Dimension(200, 150));
      center.setLayout(new GridLayout(5, 2));
      center.add(PR);
      center.add(personalCreate);
      personalCreate.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            frame.dispose();
         }
      });
      center.add(ER);
      center.add(employmentCreate);
      employmentCreate.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            frame.dispose();
         }
      });
      center.add(PerR);
      center.add(review);
      center.add(AR);
      center.add(approve);
      center.add(empty);
      center.add(logout);
      frame.setVisible(true);
   }
}

关于Java 帧处理会创建额外的空帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28756080/

相关文章:

java - 在 Java Swing 中显示图像

java - 将 ImageIcon 添加到 NetBeans 中的 jbutton 时出现空指针异常

JavaGlobal onHandlerNotFound(RequestHeader request)在play框架java中不起作用

java - Spring Rest-API - 403 禁止错误响应

java - 从 Java Swing 应用程序拖放到 Windows 资源管理器

java - 创建带有背景图像的表单(JLayeredPane)

java - Apache poi HSSFWorkbook 覆盖 XLS 模板中的样式

java - JLabel 随输入到 JTextArea 中的文本移动

Java图像抓取和显示

java - 为什么我的 JFrame 程序不会更改背景颜色?