2009-02-20 368 views
3

我想在java中製作一個GUI,但JMenuBar給了我兩天的時間。有人能告訴我爲什麼它沒有顯示出來嗎?爲什麼我的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(); 

    } 
} 

回答

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

    } 
} 

與菜單欄,一切都顯示出來。如果您將內容添加到內容窗格的中心(默認爲邊框佈局),則中心會自動填充整個內容區域,您無需調整任何內容。

這顯示爲一個菜單欄的窗口,一切工作正常。

你在做什麼平臺?我在Vista上,我得到了我期望看到的。

0

當我編譯並運行它,它顯示了與文件和編輯菜單項的菜單欄。你是否期待更多?

此外,利用你的講座SelectionFrame

編輯: 有一件事我忘了看,你的代碼和這裏的每一個答案是技術上的錯誤。通常情況下,它正常工作,但除非您處於AWT worker thread之內,否則不允許您對Swing組件執行任何操作。

通常你不必去想工作線程多,因爲每一個,從你的窗口事件將是工作線程反正,但忘掉它,當你建立你的初始frame--的傾向而且往往不是它只是起作用。

Sun曾經建議您可以使用AWT線程外部的組件,直到窗口實現(使用pack()或setVisible(true)),但是this is no longer considered safe

解決此問題的最簡單方法可能是讓您的主要人員在創建SelectionFrame之前創建一個擺動工作線程。

這將解決您的問題的機會只有50-50,但您在GUI上工作時仍應考慮此問題。

+0

每次我編譯並運行它時,我都沒有收到任何東西。你能告訴我你使用的是什麼JDK嗎? – William 2009-02-20 18:59:04

0

sel.setVisible(true);

應該是您最後一次調用的內容......

1

您使用的是哪個Java版本?我的系統上的菜單欄在1.6.0_10中顯示正常。嘗試包裝你的主要方法的主體在invokeLater()調用,這樣它運行在正確的線程,就像這樣:

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. 
      } 
     }); 
    } 
0

而且,僅僅是調用sel.setVisible(true);請援引sel.pack();

請注意,除了的setSize最好使用setPreferredSize,這是在幀封裝期間的槓桿作用。

與您的問題沒有直接關係,但仍然 - 使用Swing時,使用良好的佈局管理器是一個巨大的時間和沮喪的救星。 MigLayout簡直就是一個出色的一站式佈局管理器。

1

變成你HAVE在JFrame的構造函數中設置JMenuBar。我想到了這一點,同時查看了我的代碼和標記的答案代碼之間的差異。

謝謝你的精彩答案,約翰加德納。沒有你,我最有可能被困在幾個月。

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設置在構造函數的外部,並且在swing-thread-safe是Good Practice的情況下,它不是問題的原因。