为什么 JButton 打开一个空框架而不是调用 PMotion class?

Why is JButton opening an empty frame instead of calling PMotion class?

我有两个 java 文件(classes)PMotion.java 和 Menu.java。

Menu.java 有一个按钮。当我按下那个按钮时,我希望它处理当前的 Menu.java 帧并转到 PMotion.java class。正如您在文件 Menu.java 中看到的,我有

 new PMotion().setVisible(true);
            frame.dispose();

frame.dispose();有效,因为它关闭 Menu.java。但它并没有打开 PMotion.java,而是打开了一个空白的 JFrame。请注意:我只复制了 PMotion.java 中的相关代码 - 实际上,它是一个功能完备的应用程序。感谢您的帮助!

PMotion.java

import java.awt.EventQueue;
import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextPane;
import javax.swing.JTextArea;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JSeparator;
import javax.swing.JScrollBar;


public class PMotion extends JFrame {

    private JFrame frame;


    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    PMotion window = new PMotion();
                    window.frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public PMotion() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame("Projectile Motion");
        frame.setBounds(100, 100, 800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.setResizable(false);

Menu.java

        JButton btnProjectile = new JButton("Projectile");
        btnProjectile.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                new PMotion().setVisible(true);
                frame.dispose();


            }
        });
        btnProjectile.setBounds(260, 137, 117, 29);
        frame.getContentPane().add(btnProjectile);
    }
}

为什么您的 class 扩展 JFrame 然后在构造函数中创建一个新的 JFrame?

你要么:

  1. 扩展 JFrame(这不是一个好主意),或者
  2. 创建一个新的 JFrame(...)

但你不会两者都做。

//frame = new JFrame("Projectile Motion");
frame = this;

在您的情况下,您可以只使用上面的代码,因为 PMotion 已经是一个 JFrame。

I only copied the relevant code from PMotion.java - in reality, it is a fully working application.

不过,如果不猜测就无法完全回答,将来,您需要创建并 post 一个有效的 minimal example program(请阅读 link -- 它是如果您以后要在此站点上提问,这很重要),但只要看一眼您所做的一小段代码 post,您的 PMotion class 就会创建 two 创建时的 JFrame,一个,您正在显示的 PMotion class,以及一个单独的 JFrame within PMotion class,一个你没有显示的,我猜你把一些(大多数???)你的 GUI 组件放到这个单独的 JFrame 中。

解决方案 1:简化!让 PMotion 扩展 JFrame 并让它包含 GUI 组件,并摆脱它包含的次要不必要的 JFrame。

更好的解决方案:如果您拥有扩展 JFrame 的 classes,您将自己画在角落里,迫使您创建和显示 JFrame,而这通常需要更大的灵活性。事实上,我敢说我创建的和看到的大多数 Swing GUI 代码 没有 扩展 JFrame,事实上,您很少会想做这个。更常见的是,您的 GUI classes 将适用于创建 JPanel,然后可以将其放入 JFrames 或 JDialogs,或 JTabbedPanes,或通过 CardLayouts 在任何需要的地方进行交换。这将大大增加您的 GUI 编码的灵活性。而是使用 CardLayout 创建 JPanel 和交换视图。有关为什么这很重要的更多信息,请参阅 The Use of Multiple JFrames, Good/Bad Practice?

单独的问题:frame.getContentPane().setLayout(null);。请不要这样做。虽然空布局和 setBounds() 对于 Swing 新手来说似乎是创建复杂 GUI 的最简单和最好的方法,但您创建的 Swing GUI 越多,您在使用它们时就会 运行 遇到更严重的困难。它们不会在 GUI 调整大小时调整您的组件的大小,它们是皇家 来增强或维护的,当放置在滚动窗格中时它们完全失败,当在所有平台或不同的屏幕分辨率上查看时它们看起来很糟糕来自原来的