Fickle JMenuBar - PullRequest
       28

Fickle JMenuBar

1 голос
/ 12 января 2010

Я запускал следующий код 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 ]

2 голосов
/ 12 января 2010

Поскольку вы переопределяете способ рисования JFrame, вы просто полностью игнорируете рисование палитры JMenu.

Не делайте JFrame подклассами, используйте пользовательский компонент, вот быстрое редактирование вашего кода, не задумываясь об этом, я просто переместил некоторые части.

У меня это работает в 100% случаев:

работает нормально вот так 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) {      
    }

}

EDIT

Ваша проблема здесь:

    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, все еще в силе.

0 голосов
/ 12 января 2010

В вашем коде куча ошибок. Numero uno заключается в том, что вам не следует переопределять метод paint() JFrame. Вместо этого вам следует создать некоторый JComponent, реализовать его метод paintComponent, а затем add() этот компонент в contentPane вашего JFrame.

Редактировать: комментарии Оскара тоже все хорошо!

0 голосов
/ 12 января 2010

Прежде всего, вы используете плохой стиль скобок. Но это не проблема здесь.

В строке 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)

GUI.java в строке 41:

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

Здесь ваша переменная bs равна нулю, метод getBufferStrategy возвратил пустое значение вместо правильной ссылки на объект. Зачем? Я не знаю, вы мне ответите. О чем это getBufferStrategy? 1018 *

Но по крайней мере оттуда я вижу, что вы получаете NullPointerException, попробуйте добавить это printStackTrace, чтобы увидеть, что печатает для вас. не просто игнорировать их

...