Java 如果我将JPanel和JFrame子类化,为什么我的JFrame保持为空?

Java 如果我将JPanel和JFrame子类化,为什么我的JFrame保持为空?,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我正在尝试为我的Java应用程序编写自定义JFrame和JPanel。目前,我只想要一个在屏幕中间有一个开始按钮的JPanel。下面是我的代码: package gui; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; @SuppressWarnings("serial") public class SubitizingFrame extends JF

我正在尝试为我的Java应用程序编写自定义JFrame和JPanel。目前,我只想要一个在屏幕中间有一个开始按钮的JPanel。下面是我的代码:

package gui;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class SubitizingFrame extends JFrame implements KeyListener {

    public SubitizingFrame() {
        super("Subitizing");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addKeyListener(this);
        add(new LaunchPanel());

        pack();
        setVisible(true);
    }

    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_F5)
            System.out.println("F5 pressed");
    }

    public void keyReleased(KeyEvent e) {

    }

    public void keyTyped(KeyEvent e) {

    }
}
这是我的小组:

package gui;

import instructions.Settings;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class LaunchPanel extends JPanel implements ActionListener {

    private JButton startButton;

    public LaunchPanel() {
        int width = Settings.getScreenSizeX(), height = Settings.getScreenSizeY();
        setPreferredSize(new Dimension(width, height));
        setLayout(null);
        startButton = new JButton("Start");
        startButton.setLocation((width/2) - (startButton.getWidth()/2), (height/2) - (startButton.getHeight()/2));
        add(startButton);
    }

    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
}

但是当应用程序启动时,我什么也看不到。只有一个大的灰色屏幕。

如果您不使用任何LayoutManager(顺便说一句,您可能应该使用),那么您还需要调整面板的位置(以及它的位置)

尽管我们强烈建议您使用布局管理器,但您可以在不使用布局管理器的情况下执行布局。通过将容器的布局属性设置为null,可以使容器不使用布局管理器。使用这种称为绝对定位的策略,您必须指定容器中每个组件的大小和位置。绝对定位的一个缺点是,调整顶级容器的大小时,绝对定位不能很好地调整。它也不能很好地适应用户和系统之间的差异,例如不同的字体大小和地区

发件人:

建议:

  • 避免使用空布局,因为这会使您的应用程序难以升级和维护,并可能使其非常难看,甚至在具有不同操作系统或屏幕分辨率的设备上不可用
  • 如果您让您的JPanel使用GridBagLayout并在不使用GridBagConstraints的情况下向其添加单个组件,它将被放置在JPanel的中心
  • 您几乎不需要或应该扩展JFrame,只需要偶尔扩展JPanel。通常,最好通过组合而不是继承来增强GUI类
  • 避免让“视图”或gui类实现侦听器接口。这对于“玩具”程序来说是可以的,但一旦您的应用程序获得任何可感知的大小或复杂性,就很难维护
请勿使用空布局。如果您只需使用
JPanel
的默认布局管理器(即
FlowLayout
),则带有“自动”的
JButton
将放在中间。此外,为了将<代码> jFrase>代码放置在屏幕的中间,调用.
由于很难说出“屏幕”是什么意思,本例显示了如何将
JButton
集中在
JPanel
中的
JFrame
中,然后集中在监视器上

public final class CenterComponentsDemo {

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                createAndShowGUI();                 
            }
        });
    }

    private static void createAndShowGUI(){
        final JFrame frame = new JFrame("Center Components Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new ButtonPane());
        frame.setSize(new Dimension(300, 100)); // Done for demo
        //frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static class ButtonPane extends JPanel{
        public ButtonPane(){
            super();
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            setBackground(Color.PINK);
            final JButton button = new JButton("Start");
            button.setAlignmentX(Component.CENTER_ALIGNMENT);
            add(Box.createVerticalGlue());
            add(button);
            add(Box.createVerticalGlue());
        }
    }
}

不要使用键盘侦听器。Swing设计用于键绑定。有关更多信息,请阅读上的Swing教程部分

本教程还有一节介绍如何使用布局管理器,您应该阅读该节。您不应使用空布局创建GUI。

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

public class LaunchPanel extends JPanel {

    private JButton startButton;

    public LaunchPanel() {
        int width = 200, height = 100;
        setPreferredSize(new Dimension(width, height));
        setLayout(new GridBagLayout());
        startButton = new JButton("Start");
        add(startButton);
        setBorder( new LineBorder(Color.RED, 2));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JOptionPane.showMessageDialog(null, new LaunchPanel());
            }
        });
    }
}

这不管用。我在jpanel中添加了setLocation和setSize。问题仍然存在。请删除setlayout(null)行。让默认的FlowLayout完成它的工作。@reising1:Nah,在您问题中的代码中,您是在设置面板的大小,而不是按钮-add
startButton.setSize(…)
+1任何建议不使用空布局的答案都需要投票。+1任何建议不使用空布局的答案都需要投票。顺便问一下-为什么要扩展
JFrame
JPanel
?在这种情况下似乎没有必要。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class LaunchPanel extends JPanel {

    private JButton startButton;

    public LaunchPanel() {
        int width = 200, height = 100;
        setPreferredSize(new Dimension(width, height));
        setLayout(new GridBagLayout());
        startButton = new JButton("Start");
        add(startButton);
        setBorder( new LineBorder(Color.RED, 2));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JOptionPane.showMessageDialog(null, new LaunchPanel());
            }
        });
    }
}