简体   繁体   English

如果我继承 JPanel 和 JFrame,为什么我的 JFrame 保持为空?

[英]Why does my JFrame stay empty, if I subclass JPanel and JFrame?

I'm trying to write custom JFrame and JPanel for my Java application.我正在尝试为我的 Java 应用程序编写自定义 JFrame 和 JPanel。 Currently, I just want to have a JPanel with a start button in the very middle of the screen.目前,我只想在屏幕中间有一个带有开始按钮的 JPanel。 So, here's the code I have:所以,这是我的代码:

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) {

    }
}

and here is my panel:这是我的面板:

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

    }
}

But when the application launches, I don't see anything.但是当应用程序启动时,我什么也看不到。 Just a big gray screen.只是一个灰色的大屏幕。

Do not use a null layout .不要使用 null 布局 If you simply use the default layout manager of JPanel (ie FlowLayout ), the JButton with "automagically" be placed in the center.如果您只是使用JPanel的默认布局管理器(即FlowLayout ),“自动”的JButton将被放置在中心。 Also, in order to place the JFrame in the middle of the screen, invoke setLocationRelativeTo(null) .此外,为了将JFrame放在屏幕中间,调用setLocationRelativeTo(null)


Since it's hard to tell what you mean by "screen", this example shows how you center a JButton in a JPanel in a JFrame , that is then centered on the monitor.由于很难说出“屏幕”的含义,因此此示例显示了如何在JFrameJPanel中将JButton居中,然后在显示器上居中。

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());
        }
    }
}

在此处输入图像描述

If you don't use any LayoutManager (which btw you probably should), then you'll need to set the size of the panel as well (along with its position).如果您不使用任何 LayoutManager(顺便说一句,您可能应该使用它),那么您还需要设置面板的大小(以及它的位置)。

Although we strongly recommend that you use layout managers, you can perform layout without them.尽管我们强烈建议您使用布局管理器,但您可以在没有它们的情况下执行布局。 By setting a container's layout property to null, you make the container use no layout manager.通过将容器的布局属性设置为 null,您可以使容器不使用布局管理器。 With this strategy, called absolute positioning, you must specify the size and position of every component within that container .使用这种称为绝对定位的策略,您必须指定该容器中每个组件的大小和 position One drawback of absolute positioning is that it does not adjust well when the top-level container is resized.绝对定位的一个缺点是当顶层容器调整大小时它不能很好地调整。 It also does not adjust well to differences between users and systems, such as different font sizes and locales.它也不能很好地适应用户和系统之间的差异,例如不同的字体大小和语言环境。

From: http://download.oracle.com/javase/tutorial/uiswing/layout/using.html来自: http://download.oracle.com/javase/tutorial/uiswing/layout/using.html

Recommendations:建议:

  • Avoid using null layout as this makes your app difficult to upgrade and maintain and makes it potentially very ugly or even non-usable on boxes with different OS's or screen resolutions.避免使用 null 布局,因为这会使您的应用程序难以升级和维护,并使其在具有不同操作系统或屏幕分辨率的机器上可能非常难看甚至无法使用。
  • If you have your JPanel use a GridBagLayout and add a single component to it without using GridBagConstraints, it will be placed in the center of the JPanel.如果您让 JPanel 使用 GridBagLayout 并向其添加单个组件而不使用 GridBagConstraints,它将被放置在 JPanel 的中心。
  • You almost never have to or should extend JFrame and only infrequently need to extend JPanel.您几乎不必或应该扩展 JFrame 并且很少需要扩展 JPanel。 Usually it's better to enhance your GUI classes through composition rather than inheritance.通常最好通过组合而不是 inheritance 来增强您的 GUI 类。
  • Avoid having your "view" or gui classes implement your listener interfaces.避免让您的“视图”或 gui 类实现您的侦听器接口。 This is OK for "toy" programs, but as soon as your application gains any appreciable size or complexity, this gets hard to maintain.这对于“玩具”程序来说是可以的,但是一旦您的应用程序获得任何明显的大小或复杂性,这将很难维护。
addKeyListener(this); 

Don't use KeyListeners.不要使用 KeyListener。 Swing was designed to be used with Key Bindings. Swing 旨在与键绑定一起使用。 Read the section from the Swing tutorial on How to Use Key Bindings for more information.阅读 Swing 教程中有关如何使用键绑定的部分以获取更多信息。

The tutorial also has a section on Using Layout Manager which you should read.本教程还有一个关于Using Layout Manager的部分,您应该阅读它。 You should not create GUI's with a null layout.您不应使用 null 布局创建 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());
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM