JFrame 不会显示多个 JPanel

JFrame Won't Display Multiple JPanels

我又一次在编写一个简单的 Java 程序,但我遇到了一些问题。我在 JFrame 中只有 2 个面板,但它只会显示第二个面板。如果我删除了第二个,第一个就可以了。怎样才能同时显示这两个节目?

代码如下:

package counter.main;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

public static JTextField fieldName;
private JLabel labelMessage;
private JButton buttonSubmit;
private JButton buttonDerp;
private JLabel derps;
private JLabel space1;
private JLabel space2;
private JLabel space3;
private JLabel askName;
private JLabel space4;
int clicks = 0;
File MarioCoin;

//Key to access automatic "system crash" - keyDerp134
//Note - Keys are extremely useful when wanting to bypass a type of task and debugging.

JFrame frame = new JFrame("Enter Your Name");
public Main() {
    createView();

    setTitle("Enter your name");
    setSize(500, 100);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    revalidate();
    repaint();
} 

private void createView() {
    final JPanel panel = new JPanel();
    getContentPane().add(panel);
    panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 20));

    space1 = new JLabel("                ");
    space2 = new JLabel("                      ");
    space3 = new JLabel("                      ");
    space4 = new JLabel("            ");

    askName = new JLabel("Please enter your name");
    panel.add(askName);

    derps = new JLabel("0/100 Derps");
    derps.setFont(new Font( "Arial", Font.PLAIN, 18));

    fieldName = new JTextField();
    fieldName.setPreferredSize(new Dimension(150, 30));
    panel.add(fieldName);

    buttonSubmit = new JButton("Submit");
    buttonSubmit.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            String derpKey = "keyDerp134";
            String name = fieldName.getText();
            if(name.isEmpty()) {
                labelMessage.setText("Your name can't be nothing, now can it?");
                setSize(500, 135);
            } else {
                askName.setText("                      Hi, " + name + ".");
                SelectionFrame.select.setText("Select Your Material, " + name + ".");
                setSize(500, 100);
                try {
                    Thread.sleep(1000);   
                } catch(InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
                    if (name.equals(derpKey)) { 
                    clicks = 101;
                    updateCounter();
                }
                SelectionFrame.frame1.setVisible(true);    
                setVisible(false);
                buttonSubmit.setEnabled(false);
                fieldName.setEnabled(false);
                labelMessage.setText("                  " + name + ", Click -->");
                setTitle("Collect 100 Derps!");
                revalidate();
                repaint();
                buttonDerp = new JButton("Derp");
                buttonDerp.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        clicks++;
                        updateCounter();
                        URL soundURL = Main.class.getResource("/counter/main/MarioCoin.wav");
                        try {
                            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundURL);
                            Clip clip = AudioSystem.getClip();
                            clip.open(audioInputStream);
                            clip.start();
                            if (clicks >= 100) {
                                clip.stop();
                                buttonDerp.setEnabled(false);
                            }
                        } catch (IOException | UnsupportedAudioFileException | LineUnavailableException x) {
                            x.printStackTrace();
                        }
                    }
                }); 

        panel.add(buttonDerp);
        panel.add(derps);
        panel.add(space4);


        }
    }}); 
    panel.add(buttonSubmit);
    panel.add(space1);

    labelMessage = new JLabel("");
    panel.add(labelMessage);
    pack();
}

public static void main(String[] args) { 
    new Main();
    SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        new Main().setVisible(true);
        new CrashReportFrame();
        new SelectionFrame();
    }
});
}


public void updateCounter() {
    derps.setText(clicks + "/100 Derps");
    if (clicks >= 1 && clicks < 10) {
        labelMessage.setText("               Keep Going!");
    }

    if (clicks >= 10 && clicks < 50) {
        labelMessage.setText("     Keep 'em Comin'!");
    }

    if (clicks >= 50 && clicks < 70) {
        labelMessage.setText("                       Okay...");
    }

    if (clicks >= 70 && clicks < 80) {
        labelMessage.setText("  Slow down a little");
    }

    if (clicks >= 80 && clicks < 90) {
        labelMessage.setText("               Slow down, " + fieldName.getText() + "!");
    }

    if (clicks >= 90 && clicks < 100) {
        labelMessage.setText("    Stop! The system-");
    }

    if (clicks >= 100) {
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        try {
            Thread.sleep(3000);                 //1000 milliseconds is one second.
        } catch(InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
        setVisible(false);
        JOptionPane.showMessageDialog(null, "You Crashed The System!");
        //CrashReportFrame.frame2.setVisible(true);
    }
}



public void paint(Graphics g) {
    super.paint(g);
}

}

请注意,此 class ^ 中的大部分代码实际上并未激活,因为我是从我以前的程序中获取的。

这是带有 2 个面板

的 class 的代码
package counter.main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class SelectionFrame extends JFrame {

public static JLabel select = new JLabel("");
private JButton stone;
private JButton wood;
private JButton coin;
private JButton food;

static JFrame frame1 = new JFrame("Select Your Material");
public SelectionFrame() {
    createView();

    frame1.setTitle("Select Your Material");
    frame1.setResizable(false);
    frame1.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame1.setSize(400, 120);
    frame1.setLocationRelativeTo(null);

}

private void createView() {

    frame1.getContentPane().setBackground(Color.black);
    frame1.repaint();

    JPanel panel3 = new JPanel();
    frame1.getContentPane().add(panel3);
    panel3.setLayout(new FlowLayout(FlowLayout.CENTER));

    JPanel panel4 = new JPanel();
    frame1.getContentPane().add(panel4);
    panel4.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 55));

    select.setFont(new Font( "Dialog", Font.PLAIN, 18));
    panel3.add(select);

    stone = new JButton("Stone");
    panel4.add(stone);

    wood = new JButton("Wood");
    panel4.add(wood);

    coin = new JButton("Coin");
    panel4.add(coin);

    food = new JButton("Food");
    panel4.add(food);

    frame1.revalidate();
    frame1.repaint();

}

    public void paint(Graphics g3) {
    super.paint(g3);
}

}

感谢帮助:)

您将想要了解 Java Swing/AWT 布局管理器,包括 BorderLayout,它是顶级 window contentPanes 的默认布局。将组件添加到使用 BorderLayout 的容器时,如果不指定约束,则默认添加组件 BorderLayout.CENTER。这意味着以这种方式添加的最后一个组件将覆盖添加到同一位置的任何其他组件。解决方案包括:

  1. 使用 BorderLayout 约束将组件添加到使用 BorderLayout 的容器(此处为 contentPane),以便它们转到不同的 BorderLayout 位置。
  2. 使用不同的布局管理器,例如 BoxLayout 或 GridBagLayout。
  3. 嵌套 JPanel,每个都使用自己的布局管理器。这可以让您使用非常简单的代码创建复杂的 GUI。

您可以在此处找到 Swing 教程的链接,包括布局管理器教程和其他 Swing 资源:Swing Info

其他建议:

  • 避免设置任何大小。而是让布局管理器和组件自己的首选尺寸设置自己的尺寸。
  • 您当前的代码向用户抛出多个 JFrames,这对用户来说可能有些烦人,尤其是在完成之后。相反,请考虑创建 one JFrame 并使用 CardLayout 交换 JPanel "views"。
  • 您有一个扩展 JFrame 的 class 并且还有一个 JFrame 字段,其中至少有一个是多余的。
  • 让 class 扩展 JFrame 可能会让您陷入困境,迫使您创建和显示 JFrame,而这通常需要更大的灵活性。事实上,我敢说我创建的和看到的大部分 Swing GUI 代码 没有 扩展 JFrame,事实上,您很少会想做这个。更常见的是,您的 GUI classes 将适用于创建 JPanel,然后可以将其放入 JFrames 或 JDialogs,或 JTabbedPanes,或通过 CardLayouts 在任何需要的地方进行交换。这将大大增加您的 GUI 编码的灵活性。