Fickle JMenuBar

时间:2010-01-12 01:57:03

标签: swing jframe jmenubar

我运行了以下代码10次。在10次运行中,3次显示菜单栏和矩形,3只显示矩形,4只显示没有。我做错了什么?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import static java.awt.Color.*;
import java.awt.image.*;


public class GUI extends JFrame implements KeyListener, ActionListener
{
    int x, y;
    public static void main(String[] args)
    {
        new GUI();
    }
    public GUI()
    {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e)
        {
            e.printStackTrace();
        }       
        frameInit();
        setSize(1024,768);
        setDefaultCloseOperation(EXIT_ON_CLOSE);;
        setVisible(true);
        setJMenuBar(createMenuBar());
        addKeyListener(this);
        createBufferStrategy(2);
        x = 0;
        y = 49;
    }
    public void paint(Graphics gm)
    {
        BufferStrategy bs = getBufferStrategy();
        try
        {
            Graphics g = bs.getDrawGraphics(); 
            super.paint(g);
            g.setColor(WHITE);
            g.drawRect(0,0,1024,768);
            g.setColor(BLACK);
            g.fillRect(x,y,100,100);
            bs.show();
        }catch(Exception e)
        {

        }
    }
    public JMenuBar createMenuBar()
    {
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
        JMenuItem save = new JMenuItem("Save");
        save.setMnemonic(KeyEvent.VK_S);
        save.addActionListener(this);
        JMenuItem load = new JMenuItem("Load");
        load.setMnemonic(KeyEvent.VK_L);
        load.addActionListener(this);
        JMenuItem quit = new JMenuItem("Quit");
        quit.setMnemonic(KeyEvent.VK_Q);
        quit.addActionListener(this);
        fileMenu.add(save);
        fileMenu.add(load);
        fileMenu.addSeparator();
        fileMenu.add(quit);
        JMenu editMenu = new JMenu("Edit");
        editMenu.setMnemonic(KeyEvent.VK_E);
        JMenuItem undo = new JMenuItem("Undo");
        undo.setMnemonic(KeyEvent.VK_U);
        undo.addActionListener(this);
        JMenuItem redo = new JMenuItem("Redo");
        redo.setMnemonic(KeyEvent.VK_R);
        redo.addActionListener(this);
        editMenu.add(undo);
        editMenu.add(redo);
        JMenu helpMenu = new JMenu("Help");
        helpMenu.setMnemonic(KeyEvent.VK_H);
        JMenuItem controls = new JMenuItem("Controls");
        controls.setMnemonic(KeyEvent.VK_C);
        controls.addActionListener(this);
        JMenuItem about = new JMenuItem("About");
        about.setMnemonic(KeyEvent.VK_A);
        about.addActionListener(this);
        helpMenu.add(controls);
        helpMenu.addSeparator();
        helpMenu.add(about);
        menuBar.add(fileMenu);
        menuBar.add(editMenu);
        menuBar.add(helpMenu);
        menuBar.setLocation(0,23);
        return menuBar;
    }
    public void actionPerformed(ActionEvent e)
    {
        System.out.println(e.getActionCommand());
        repaint();
    }
    public void keyPressed(KeyEvent e)
    {
        if(e.getKeyCode()==KeyEvent.VK_UP)
        {
            y-=10;
        }
        if(e.getKeyCode()==KeyEvent.VK_DOWN)
        {
            y+=10;
        }
        if(e.getKeyCode()==KeyEvent.VK_LEFT)
        {
            x-=10;
        }
        if(e.getKeyCode()==KeyEvent.VK_RIGHT)
        {
            x+=10;
        }
        repaint();
    }
    public void keyReleased(KeyEvent e)
    {
    }
    public void keyTyped(KeyEvent e)
    {       
    }

}

3 个答案:

答案 0 :(得分:2)

由于你覆盖了绘制JFrame的方式,你只是完全忽略了JMenu条画。

不要将JFrame子类化,使用自定义组件,这里是对代码的快速编辑,而不用考虑太多,我只是移动一些部分。

它对我来说有100%的时间:

it works fine like this http://img706.imageshack.us/img706/1291/capturadepantalla201001l.png

//I ran the following code 10 times. Of the 10 runs, 3 showed both the menu bar and the rectangle, 3 showed only the rectangle, and 4 showed nothing at all. What am I doing wrong?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import static java.awt.Color.*;
import java.awt.image.*;


public class GUI extends JComponent implements KeyListener, ActionListener {
    private int x, y;
    public static void main(String[] args) {
        setLnF();
        // Don't subclass it just use it.
        JFrame frame = new JFrame();
        //frameInit();
        frame.setSize(1024,768);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //frame.setVisible(true);

        GUI gui = new GUI();

        frame.setJMenuBar(gui.createMenuBar());
        frame.addKeyListener( gui );    
        frame.add( gui ) ;
        frame.setVisible(true); // should be the last thing to call


    }
    private static void setLnF() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch( InstantiationException ie ) {
            ie.printStackTrace();
        } catch( IllegalAccessException iae ) {
            iae.printStackTrace();
        } catch( UnsupportedLookAndFeelException u ) {
            u.printStackTrace();
        }
    }
    public GUI() {
        //createBufferStrategy(2);
        x = 0;
        y = 49;
    }
    public void paint(Graphics gm) {
        //BufferStrategy bs = getBufferStrategy();
        try {
            Graphics g = gm; // bs.getDrawGraphics(); 
            super.paint(g);
            g.setColor(WHITE);
            g.drawRect(0,0,1024,768);
            g.setColor(BLACK);
            g.fillRect(x,y,100,100);
            //bs.show();
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
    public JMenuBar createMenuBar() {
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
        JMenuItem save = new JMenuItem("Save");
        save.setMnemonic(KeyEvent.VK_S);
        save.addActionListener(this);
        JMenuItem load = new JMenuItem("Load");
        load.setMnemonic(KeyEvent.VK_L);
        load.addActionListener(this);
        JMenuItem quit = new JMenuItem("Quit");
        quit.setMnemonic(KeyEvent.VK_Q);
        quit.addActionListener(this);
        fileMenu.add(save);
        fileMenu.add(load);
        fileMenu.addSeparator();
        fileMenu.add(quit);
        JMenu editMenu = new JMenu("Edit");
        editMenu.setMnemonic(KeyEvent.VK_E);
        JMenuItem undo = new JMenuItem("Undo");
        undo.setMnemonic(KeyEvent.VK_U);
        undo.addActionListener(this);
        JMenuItem redo = new JMenuItem("Redo");
        redo.setMnemonic(KeyEvent.VK_R);
        redo.addActionListener(this);
        editMenu.add(undo);
        editMenu.add(redo);
        JMenu helpMenu = new JMenu("Help");
        helpMenu.setMnemonic(KeyEvent.VK_H);
        JMenuItem controls = new JMenuItem("Controls");
        controls.setMnemonic(KeyEvent.VK_C);
        controls.addActionListener(this);
        JMenuItem about = new JMenuItem("About");
        about.setMnemonic(KeyEvent.VK_A);
        about.addActionListener(this);
        helpMenu.add(controls);
        helpMenu.addSeparator();
        helpMenu.add(about);
        menuBar.add(fileMenu);
        menuBar.add(editMenu);
        menuBar.add(helpMenu);
        menuBar.setLocation(0,23);
        return menuBar;
    }
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getActionCommand());
        repaint();
    }
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_UP) {
            y-=10;
        }
        if(e.getKeyCode()==KeyEvent.VK_DOWN) {
            y+=10;
        }
        if(e.getKeyCode()==KeyEvent.VK_LEFT) {
            x-=10;
        }
        if(e.getKeyCode()==KeyEvent.VK_RIGHT) {
            x+=10;
        }
        repaint();
    }
    public void keyReleased(KeyEvent e) {
    }
    public void keyTyped(KeyEvent e) {      
    }

}

修改

你的问题在这里:

    frameInit();
    setSize(1024,768);
    setDefaultCloseOperation(EXIT_ON_CLOSE);;
    setVisible(true); //<-- exaaaactly here!!
    setJMenuBar(createMenuBar());
    addKeyListener(this);
    createBufferStrategy(2);

只需将该行移至最后,它应该可以正常工作。

    frameInit();
    setSize(1024,768);
    setDefaultCloseOperation(EXIT_ON_CLOSE);;
    ///setVisible(true); //<-- exaaaactly here!!
    setJMenuBar(createMenuBar());
    addKeyListener(this);
    createBufferStrategy(2);
    setVisible( true );

我所说的关于子类化JFrame的内容仍然有效。

答案 1 :(得分:0)

首先,你使用坏支撑式。但这不是问题所在。

在第48行,你忽略了异常:

try {

} catch(Exception e) {

}

如果你添加:

e.printStackTrace();

它会告诉你问题是什么,当我跑它说:

java.lang.NullPointerException
at GUI.paint(GUI.java:41)
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:276)
at sun.awt.RepaintArea.paint(RepaintArea.java:241)
at apple.awt.ComponentModel.handleEvent(ComponentModel.java:263)

第41行的GUI.java是:

BufferStrategy bs = getBufferStrategy();
try {
    Graphics g = bs.getDrawGraphics(); // <--- this line

此处bs变量为null,方法getBufferStrategy返回null而不是有效的对象引用。为什么?我不知道,你回答我。什么是getBufferStrategy一切?

但至少从那里我看到的是,你正在NullPointerException尝试添加printStackTrace以查看为您打印的内容。的 don't just ignore them

答案 2 :(得分:0)

您的代码中存在大量错误。 Numero uno 是你不应该重写JFrame的paint()方法。相反,您应该创建一些JComponent,实现其paintComponent方法,然后将add()该组件添加到JFrame的contentPane。

编辑:奥斯卡的评论也很好!