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 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 = ne开发者_StackOverflow中文版w 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)
{
}
}
Since you're overriding the way the JFrame is painted you are simply ignoring the JMenu bar painting completely.
Don't subclass JFrame, use a custom component, here's a quick edit of your code, without thinking too much about it, I've just move some pieces.
It works 100% of the times for me:
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) {
}
}
EDIT
Your problem is here:
frameInit();
setSize(1024,768);
setDefaultCloseOperation(EXIT_ON_CLOSE);;
setVisible(true); //<-- exaaaactly here!!
setJMenuBar(createMenuBar());
addKeyListener(this);
createBufferStrategy(2);
Just move that line to the end and it should work fine.
frameInit();
setSize(1024,768);
setDefaultCloseOperation(EXIT_ON_CLOSE);;
///setVisible(true); //<-- exaaaactly here!!
setJMenuBar(createMenuBar());
addKeyListener(this);
createBufferStrategy(2);
setVisible( true );
What I said about subclassing JFrame is still valid.
First of all you're using bad brace style. But well that's not the problem here.
On line 48 you're ignoring the exception:
try {
} catch(Exception e) {
}
If you add this:
e.printStackTrace();
It will tell you what the problem is, when I ran it it said:
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 at line 41 is:
BufferStrategy bs = getBufferStrategy();
try {
Graphics g = bs.getDrawGraphics(); // <--- this line
Here your bs
variable is null, the method getBufferStrategy
returned null instead of a valid object reference. Why? I don't know, you answer me. What's that getBufferStrategy
all about?
But at least from there what I see is that your're getting a NullPointerException
try adding that printStackTrace
to see what's printing for you. don't just ignore them
There are a bunch of errors in your code. Numero uno is that you shouldn't be overriding the JFrame's paint()
method. You should, instead, create some JComponent, implement its paintComponent
method, then add()
that component to your JFrame's contentPane.
Edit: Oscar's comments are all good, too!
精彩评论