Swing 易变的吉门努巴

Swing 易变的吉门努巴,swing,jframe,jmenubar,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, ActionLis

我运行了以下代码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)
    {       
    }

}

首先,你使用的是糟糕的支撑方式。但这不是问题所在

在第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
BufferStrategy bs=getBufferStrategy();
试一试{

Graphics g=bs.getDrawGraphics();//您的代码中存在大量错误。最重要的是您不应该覆盖JFrame的
paint()
方法。相反,您应该创建一些JComponent,实现其
paintComponent
方法,然后
将该组件添加到JFrame的contentPane中


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

因为你覆盖了JFrame的绘制方式,你只是完全忽略了JMenu栏的绘制

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

对我来说,它100%都有效:

编辑

你的问题是:

    frameInit();
    setSize(1024,768);
    setDefaultCloseOperation(EXIT_ON_CLOSE);;
    setVisible(true); //<-- exaaaactly here!!
    setJMenuBar(createMenuBar());
    addKeyListener(this);
    createBufferStrategy(2);
frameInit();
设置大小(1024768);
setDefaultCloseOperation(关闭时退出);;

setVisible(true);//事实上,您不应该首先将JFrame子类化!您的代码不是真正的JFrame子类,您只是在使用它。出于好奇,将JFrame子类化有什么不好的,因为通过继承,您将类深深地绑定到JFrame,在这种情况下,这是必需的。您应该继承(子类)当您重新定义类的行为时,当功能发生变化时,而不仅仅是当数据发生变化时。在本例中,您只是使用JFrame,没有理由继承它。此外,继承使执行单元测试更加困难(因为要测试代码,您必须始终创建JFrame)在使用组合时,您可以单独测试您的功能。继承在OOP中占有一席之地,但不应滥用。BufferStrategy是允许在JFrame中使用多缓冲的类getBufferStrategy是允许您获取BufferStrategy的JFrame方法(假设您创建了一个)然后getDrawGraphics允许您获取与该BufferStrategy关联的图形对象(或者至少,这是我对它的基本理解)NullPointerException发生在一些关于在肮脏区域绘画的事情上有没有关于我如何解决这个问题的想法你是如何回答这个问题两次的?@koray我刚刚回答了,可能已经不可能了,但3年前是这样了
    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 );