JMenuBar 在连续运行中是否显示
JMenuBar is / is not Displayed in sucsessive runs
大家好,我已经被动地使用过这个页面很多次了,因为有很多很好的解释,但是今天到目前为止,我不得不自己问一个问题,因为我认为发生了什么很奇怪.
我使用来自 Javax.Swing 的 JFrame 编写了一个小游戏,其中包含一个 JMenu。该程序实际上运行良好,并且 JMenuBar 也在运行并显示。但是,当我 运行 程序时,可能会发生菜单未显示的情况,尽管它实际上在那里(我可以使用快捷方式)。当显示菜单时,在我看来或多或少是随意的。我没有更改任何代码,并且在 eclipse 中没有警告或错误,但是有一次我看不到菜单栏。
到目前为止,我看不出这种情况何时发生的任何模式。
我只能怀疑这与我关闭 Frame/program 的方式有关
以及由于我的 OS 在后台发生的事情。
Windows 7 终极 SP1
Eclipse Java 开发工具版本:3.10.1.v20150204-1700
Java 版本 1.8.0_45
这是我的 Class 生成 JFrame 的代码:
然后在 actionhandler 中有一些东西来启动游戏等等,还有一个 main class 来调用 Frame class.
的构造函数
public class Frame extends JFrame implements ActionListener{
private Screen s;
public Frame()
{
//---set frame
this.setUndecorated(false);
this.setTitle("Super Tick Tack Toe");
ImageIcon frameIcon = new ImageIcon(Frame.class.getResource("res/STTT_icon_64x64.png"));
this.setIconImage(frameIcon.getImage());
this.setDefaultCloseOperation(Frame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setResizable(false);
this.setSize(windowWidth,windowHeight);
this.setLocationRelativeTo(null);
//---game Menu
//---exit
JMenuItem exit = new JMenuItem("exit");
KeyStroke escKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
exit.setAccelerator(escKeyStroke);
exit.addActionListener(this);
//---load
JMenuItem save = new JMenuItem("save game");
KeyStroke saveKeyStroke = KeyStroke.getKeyStroke("control S");
save.setAccelerator(saveKeyStroke);
save.addActionListener(this);
//---save
JMenuItem load = new JMenuItem("load game");
KeyStroke loadKeyStroke = KeyStroke.getKeyStroke("control L");
load.setAccelerator(loadKeyStroke);
load.addActionListener(this);
//---preferences
JMenuItem preferences = new JMenuItem("preferences");
preferences.addActionListener(this);
JMenuItem newGame = new JMenuItem("new game");
KeyStroke newGameKeyStroke = KeyStroke.getKeyStroke("F2");
newGame.setAccelerator(newGameKeyStroke);
newGame.addActionListener(this);
//---pack game
JMenu game = new JMenu("game");
game.add(newGame);
game.add(new JSeparator()); // SEPARATOR
game.add(save);
game.add(load);
game.add(new JSeparator()); // SEPARATOR
game.add(preferences);
game.add(new JSeparator()); // SEPARATOR
game.add(exit);
//---help Menu
//---about
JMenuItem about = new JMenuItem("about STTT");
about.addActionListener(this);
KeyStroke aboutKeyStroke = KeyStroke.getKeyStroke("F12");
about.setAccelerator(aboutKeyStroke);
//---rules
JMenuItem rules = new JMenuItem("rules");
rules.addActionListener(this);
KeyStroke rulesKeyStroke = KeyStroke.getKeyStroke("F1");
rules.setAccelerator(rulesKeyStroke);
//---pack help
JMenu help = new JMenu("help");
help.add(rules);
help.add(new JSeparator()); // SEPARATOR
help.add(about);
//---pack menu bar
JMenuBar mb = new JMenuBar();
mb.add(game);
mb.add(help);
this.setJMenuBar(mb);
s = new Screen();
s.setBounds(0, 0, windowWidth, windowHeight);
add(s);
}
public void repaint()
{
s.repaint();
}
private class Screen extends JLabel{
private static final long serialVersionUID = 1L;
@Override
public void paintComponent(Graphics gg)
{
super.paintComponent(gg);
if(SuperTickTackToe.playing){
Graphics2D g = (Graphics2D) gg;
STTTgame.draw(g);
}
}
}
this.setVisible(true);
this.setResizable(false);
this.setSize(windowWidth,windowHeight);
this.setLocationRelativeTo(null);
不要在构造函数的开头调用上述代码。
在创建所有组件并将其添加到框架后,您应该调用 setVisible(true) 作为框架构造函数中的最后一条语句。
s = new Screen();
s.setBounds(0, 0, windowWidth, windowHeight);
add(s);
this.setResizable(false);
this.setSize(windowWidth,windowHeight);
this.setLocationRelativeTo(null);
this.setVisible(true);
另外,既然JFrame包含标题栏和边框,那么Screen和JFrame的大小怎么能一样呢?你真的应该只使用框架的 pack() 方法来确定它的大小。然后,您添加到框架中的组件的首选大小将用于确定框架大小。
大家好,我已经被动地使用过这个页面很多次了,因为有很多很好的解释,但是今天到目前为止,我不得不自己问一个问题,因为我认为发生了什么很奇怪.
我使用来自 Javax.Swing 的 JFrame 编写了一个小游戏,其中包含一个 JMenu。该程序实际上运行良好,并且 JMenuBar 也在运行并显示。但是,当我 运行 程序时,可能会发生菜单未显示的情况,尽管它实际上在那里(我可以使用快捷方式)。当显示菜单时,在我看来或多或少是随意的。我没有更改任何代码,并且在 eclipse 中没有警告或错误,但是有一次我看不到菜单栏。
到目前为止,我看不出这种情况何时发生的任何模式。 我只能怀疑这与我关闭 Frame/program 的方式有关 以及由于我的 OS 在后台发生的事情。
Windows 7 终极 SP1 Eclipse Java 开发工具版本:3.10.1.v20150204-1700 Java 版本 1.8.0_45
这是我的 Class 生成 JFrame 的代码: 然后在 actionhandler 中有一些东西来启动游戏等等,还有一个 main class 来调用 Frame class.
的构造函数public class Frame extends JFrame implements ActionListener{
private Screen s;
public Frame()
{
//---set frame
this.setUndecorated(false);
this.setTitle("Super Tick Tack Toe");
ImageIcon frameIcon = new ImageIcon(Frame.class.getResource("res/STTT_icon_64x64.png"));
this.setIconImage(frameIcon.getImage());
this.setDefaultCloseOperation(Frame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setResizable(false);
this.setSize(windowWidth,windowHeight);
this.setLocationRelativeTo(null);
//---game Menu
//---exit
JMenuItem exit = new JMenuItem("exit");
KeyStroke escKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
exit.setAccelerator(escKeyStroke);
exit.addActionListener(this);
//---load
JMenuItem save = new JMenuItem("save game");
KeyStroke saveKeyStroke = KeyStroke.getKeyStroke("control S");
save.setAccelerator(saveKeyStroke);
save.addActionListener(this);
//---save
JMenuItem load = new JMenuItem("load game");
KeyStroke loadKeyStroke = KeyStroke.getKeyStroke("control L");
load.setAccelerator(loadKeyStroke);
load.addActionListener(this);
//---preferences
JMenuItem preferences = new JMenuItem("preferences");
preferences.addActionListener(this);
JMenuItem newGame = new JMenuItem("new game");
KeyStroke newGameKeyStroke = KeyStroke.getKeyStroke("F2");
newGame.setAccelerator(newGameKeyStroke);
newGame.addActionListener(this);
//---pack game
JMenu game = new JMenu("game");
game.add(newGame);
game.add(new JSeparator()); // SEPARATOR
game.add(save);
game.add(load);
game.add(new JSeparator()); // SEPARATOR
game.add(preferences);
game.add(new JSeparator()); // SEPARATOR
game.add(exit);
//---help Menu
//---about
JMenuItem about = new JMenuItem("about STTT");
about.addActionListener(this);
KeyStroke aboutKeyStroke = KeyStroke.getKeyStroke("F12");
about.setAccelerator(aboutKeyStroke);
//---rules
JMenuItem rules = new JMenuItem("rules");
rules.addActionListener(this);
KeyStroke rulesKeyStroke = KeyStroke.getKeyStroke("F1");
rules.setAccelerator(rulesKeyStroke);
//---pack help
JMenu help = new JMenu("help");
help.add(rules);
help.add(new JSeparator()); // SEPARATOR
help.add(about);
//---pack menu bar
JMenuBar mb = new JMenuBar();
mb.add(game);
mb.add(help);
this.setJMenuBar(mb);
s = new Screen();
s.setBounds(0, 0, windowWidth, windowHeight);
add(s);
}
public void repaint()
{
s.repaint();
}
private class Screen extends JLabel{
private static final long serialVersionUID = 1L;
@Override
public void paintComponent(Graphics gg)
{
super.paintComponent(gg);
if(SuperTickTackToe.playing){
Graphics2D g = (Graphics2D) gg;
STTTgame.draw(g);
}
}
}
this.setVisible(true);
this.setResizable(false);
this.setSize(windowWidth,windowHeight);
this.setLocationRelativeTo(null);
不要在构造函数的开头调用上述代码。
在创建所有组件并将其添加到框架后,您应该调用 setVisible(true) 作为框架构造函数中的最后一条语句。
s = new Screen();
s.setBounds(0, 0, windowWidth, windowHeight);
add(s);
this.setResizable(false);
this.setSize(windowWidth,windowHeight);
this.setLocationRelativeTo(null);
this.setVisible(true);
另外,既然JFrame包含标题栏和边框,那么Screen和JFrame的大小怎么能一样呢?你真的应该只使用框架的 pack() 方法来确定它的大小。然后,您添加到框架中的组件的首选大小将用于确定框架大小。