2011-08-15 42 views
3

我正在尝试为我的Java应用程序编写自定义JFrame和JPanel。目前,我只想在屏幕中间有一个启动按钮的JPanel。所以,这里是我的代码:为什么我的JFrame保持空白,如果我继承JPanel和JFrame?

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 

    } 
} 

但应用程序启动时,我看不到任何东西。只是一个大灰色的屏幕。

回答

4

请勿使用空布局。如果您仅使用默认布局管理器JPanel(即FlowLayout),则将“自动”设置为JButton置于中间。此外,为了将JFrame放置在屏幕中间,请调用setLocationRelativeTo(null)


因为它是很难告诉你的“屏幕”的意思,这个例子说明了如何在一个JFrame中心在JPanel一个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()); 
     } 
    } 
} 

enter image description here

+0

+1建议不使用空布局的任何答案都需要提高。 – camickr

3

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

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

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

+0

但我设置面板的最佳尺寸已经... – CodeGuy

+0

这行不通。我将setLocation和setSize添加到我的jpanel中。问题依然存在。 – CodeGuy

+0

摆脱setlayout(null)行。让默认的FlowLayout完成它的工作。 – camickr

3

建议:使用空布局,这使得你的应用程序很难升级和维护,使得它有可能

  • 避免很丑或者与不同的盒子甚至不可使用操作系统或屏幕分辨率。
  • 如果你有你的JPanel使用GridBagLayout并添加一个组件到它而不使用GridBagConstraints,它将被放置在JPanel的中心。
  • 您几乎从不需要或应该扩展JFrame,并且很少需要扩展JPanel。通常最好通过组合而不是继承来增强GUI类。
  • 避免让你的“视图”或GUI类实现你的监听器接口。这对于“玩具”程序是可以的,但只要您的应用程序获得了可观的大小或复杂度,就很难维护。
+0

+1建议不使用空布局的任何答案都需要提高。 – camickr

3
addKeyListener(this); 

不要使用KeyListeners。Swing被设计为与键绑定一起使用。请参阅How to Use Key Bindings上的Swing教程部分以获取更多信息。

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

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

顺便说一句 - 为什么扩展'JFrame'或'JPanel'?在这种情况下似乎没有必要。 –