为什么我的JMenuBar不会出现?

时间:2009-02-20 18:48:19

标签: java user-interface swing

我正在尝试在java中创建一个GUI,但是JMenuBar给了我两天的艰难时间。有人可以告诉我它为什么没有出现吗?

import java.awt.*;
import javax.swing.*;
import javax.swing.JPanel;
import java.awt.event.*;
import java.awt.image.*;     
import java.io.*;
import java.util.Arrays;
import javax.imageio.ImageIO;

public class selectionFrame extends JFrame
 {
  Font name;
  Font title;

  public void setup() //can't use constructer because this isn't given a size until after it is constructed.
  { 
   //getContentPane().add(menuBar);
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   getContentPane().setLayout(new FlowLayout());
   //getContentPane().add(j);

   setJMenuBar(createMenuBar());
   //getContentPane().add(createMenuBar());  
  }

  public JMenuBar createMenuBar()
  {
   JMenuBar menuBar;
   JMenu m_file;
   JMenuItem mi_save;
   JMenuItem mi_load;

   JMenu m_edit;
   JMenuItem mi_tileHeight;
   JMenuItem mi_tileWidth;

   menuBar = new JMenuBar();
   m_file = new JMenu("File");
   m_edit = new JMenu("Edit");

   mi_save = new JMenuItem("Save file", KeyEvent.VK_S);
   mi_load = new JMenuItem("Load file", KeyEvent.VK_L);
   mi_tileHeight = new JMenuItem("Set tile height", KeyEvent.VK_H);
   mi_tileWidth = new JMenuItem("Set tile width", KeyEvent.VK_W);

   menuBar.add(m_file);
   m_file.add(mi_save);
   m_file.add(mi_load);

   menuBar.add(m_edit);
   m_edit.add(mi_tileHeight);
   m_edit.add(mi_tileWidth);

   return menuBar;
  }

  public static void main(String[] args) //run
  { 
   selectionFrame sel = new selectionFrame();
   sel.setLocationRelativeTo(null);
   sel.setSize((int) 400 + (sel.getInsets().left + sel.getInsets().right),(int) 400  + (sel.getInsets().top + sel.getInsets().bottom));

   sel.setVisible(true);
   sel.setTitle("Tiles/Meta");
   sel.setResizable(false);
   sel.setFocusable(true);
   sel.getContentPane().setSize(sel.getSize());
   sel.setLocation((int) sel.getX() - (sel.getWidth()/2),(int) sel.getY() -  (sel.getHeight()/2));
   sel.setup();
   sel.repaint();

   } 
 }

7 个答案:

答案 0 :(得分:5)

那里有很多额外的代码。

public class SelectionFrame extends JFrame
{
    Font name;
    Font title;

    public SelectionFrame()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setJMenuBar(createMenuBar());
    }

    public JMenuBar createMenuBar()
    {
        JMenuBar menuBar;
        JMenu m_file;
        JMenuItem mi_save;
        JMenuItem mi_load;

        JMenu m_edit;
        JMenuItem mi_tileHeight;
        JMenuItem mi_tileWidth;

        menuBar = new JMenuBar();
        m_file = new JMenu("File");
        m_edit = new JMenu("Edit");

        mi_save = new JMenuItem("Save file", KeyEvent.VK_S);
        mi_load = new JMenuItem("Load file", KeyEvent.VK_L);
        mi_tileHeight = new JMenuItem("Set tile height",
        KeyEvent.VK_H);
        mi_tileWidth = new JMenuItem("Set tile width",
        KeyEvent.VK_W);

        menuBar.add(m_file);
        m_file.add(mi_save);
        m_file.add(mi_load);

        menuBar.add(m_edit);
        m_edit.add(mi_tileHeight);
        m_edit.add(mi_tileWidth);

        return menuBar;
    }

    public void main( String args[] )
    {

        SelectionFrame sel = new SelectionFrame();
        sel.setLocationRelativeTo(null);
        sel.setSize(400 + (sel.getInsets().left + > sel.getInsets().right), 400
        + (sel.getInsets().top + sel.getInsets().bottom));

        sel.setTitle("Tiles/Meta");
        sel.setResizable(false);
        sel.setFocusable(true);

        sel.getContentPane().add( new JLabel( "Content", SwingConstants.CENTER),
         BorderLayout.CENTER );
        sel.setLocation(sel.getX() - (sel.getWidth() / 2), sel.getY() - >             (sel.getHeight() / 2));
        sel.setVisible(true);

    }
}

显示菜单栏和所有内容。如果您将内容添加到内容窗格的CENTER(默认情况下为边框布局),则中心会自动填充整个内容区域,您无需调整任何内容。

这显示为带有菜单栏的窗口,一切正常。

你在做什么平台?我在Vista上,我得到了我期望看到的东西。

答案 1 :(得分:1)

您使用的是哪个Java版本?您的菜单栏在我的系统上显示为1.6.0_10。尝试在invokeLater()调用中包装main方法的主体,以便它在正确的线程上运行,如下所示:

public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                selectionFrame sel = new selectionFrame();
                sel.setLocationRelativeTo(null);
                sel.setSize((int) 400 + (sel.getInsets().left + sel.getInsets().right), 
                            (int) 400 + (sel.getInsets().top + sel.getInsets().bottom));
                sel.setTitle("Tiles/Meta");
                sel.setResizable(false);
                sel.setFocusable(true);
                sel.getContentPane().setSize(sel.getSize());
                sel.setLocation((int) sel.getX() - (sel.getWidth() / 2),
                                (int) sel.getY() - (sel.getHeight() / 2));
                sel.setup();
                sel.setVisible(true); // Follow Kendrick's advice too.
            }
        });
    }

答案 2 :(得分:1)

原来你 HAVE 在JFrame的构造函数中设置JMenuBar。在查看我的代码和标记的答案代码之间的差异时,我想出了这一点。

感谢你的精彩回答,John Gardner。没有你,我很可能会被困几个月。

答案 3 :(得分:1)

在我的情况下,我已经找到了一个缺少菜单栏的错误,我设置了 RootPane 布局,tsk tsk。 RootPane(参见例如http://download.java.net/jdk7/archive/b123/docs/api/javax/swing/JRootPane.html)控制菜单栏的布局,因此当我更改其布局管理器时,它会丢失栏。

相反,应该使用 ContentPane 来布局和添加组件,例如:

frame.getContentPane().setLayout(...);
frame.getContentPane().add(...);

供将来参考...这与可见组件无关(如OP所说,框架可见,但菜单栏不可见),我有工作代码将JMenuBar设置在构造函数之外,并且虽然摆动线程安全是良好实践,但它不是问题的原因。

答案 4 :(得分:0)

当我编译并运行它时,它会显示一个带有文件和编辑菜单项的菜单栏。你期待更多吗?

另外,将您的类 - SelectionFrame

大写

编辑: 有一件事我忘了看,你的代码和每个答案在技术上都是错误的。通常它会发生工作,但除非您在AWT worker thread,否则不允许您使用Swing组件执行任何操作。

通常你不必考虑工作线程,因为你的窗口发出的每个事件都会在工作线程上,但是当你构建初始框架时,有一种忘记它的倾向 - 不管怎样,它通常都会起作用。

Sun曾经建议您可以使用AWT线程之外的组件,直到窗口实现(使用pack()或setVisible(true)),但this is no longer considered safe

解决此问题的最简单方法可能是您的主要人员在新建SelectionFrame之前创建一个swing工作线程。

只有50%的机会可以解决您的问题,但是在使用GUI时仍然应该考虑到这一点。

答案 5 :(得分:0)

sel.setVisible(真);

应该是你打电话的最后一件事......

答案 6 :(得分:0)

此外,在调用sel.setVisible(true);之前请调用sel.pack();

请注意,使用setSize代替setPreferredSize,最好在框架打包期间使用{<1}}。

与您的问题没有直接关系,但仍然 - 使用Swing时,使用优秀的布局管理器是一个巨大的时间和挫败感。 MigLayout只是一个出色的一站式布局管理员。