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

时间:2011-08-15 23:22:06

标签: 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 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

    }
}

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

5 个答案:

答案 0 :(得分:4)

不要使用空布局。如果您只使用JPanel的默认布局管理器(即FlowLayout),则会自动将JButton与“自动”放在中心。另外,为了将JFrame放在屏幕中间,请调用setLocationRelativeTo(null)


由于“屏幕”很难说出你的意思,这个例子展示了如何将JButton放在JPanel的{​​{1}}中,然后以监视器为中心

JFrame

enter image description here

答案 1 :(得分:3)

如果您不使用任何LayoutManager(您可能应该这样做),那么您还需要set the size面板(及其位置)。

  

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

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

答案 2 :(得分:3)

建议:

  • 避免使用空布局,因为这会使您的应用难以升级和维护,并使其在具有不同操作系统或屏幕分辨率的盒子上可能非常难看甚至不可用。
  • 如果您的JPanel使用GridBagLayout并在不使用GridBagConstraints的情况下向其添加单个组件,它将被放置在JPanel的中心。
  • 你几乎从来没有或应该扩展JFrame,并且很少需要扩展JPanel。通常,最好通过组合而不是继承来增强GUI类。
  • 避免让您的“视图”或gui类实现您的侦听器接口。这对于“玩具”程序来说是可以的,但是一旦你的应用程序获得任何可观的大小或复杂性,这就很难维护。

答案 3 :(得分:3)

addKeyListener(this); 

不要使用KeyListeners。 Swing旨在与Key Bindings一起使用。有关详细信息,请阅读How to Use Key Bindings上的Swing教程中的部分。

本教程还有一个关于Using Layout Manager的部分,您应该阅读。您不应该使用null布局创建GUI。

答案 4 :(得分:3)

Centered Button

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