我目前正在开发一款小游戏,但遇到一个问题:
我有三个类,第一个是JFrame:
public class Game
{
public static void main(String[] args)
{
new Game().gui();
}
public void gui()
{
DrawPanel panel = new DrawPanel();
JFrame frame = new JFrame("Test");
//frame.add(panel);
frame.add(new MainMenu());
frame.setSize(800, 700);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
}
}
现在,我还有另外两个类,一个是mainMenu,目前仅由一个JButton组成。
我决定将菜单设为自己的类,因为稍后,我想通过按Escape来调用菜单,但是问题是(出于测试原因)我想在按下“开始”时绘制一个矩形。我尝试了不同的方法,但没有任何反应。
public class MainMenu extends JPanel implements ActionListener
{
GamePanel panel = new GamePanel();
public MainMenu()
{
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JButton b1 = new JButton("Start");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipadx = 200;
b1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
add(b1, c);
}
}
public class DrawPanel extends JPanel
{
public void paint(Graphics g)
{
g.drawRect (10, 10, 200, 200);
}
}
最佳答案
我在您的代码中发现了几个错误:
您没有将DrawPanel
添加到任何内容,因为此行
frame.add(panel);
被评论,因此,这导致我们下一个问题:
您正在覆盖
paint()
方法而不是paintComponent()
,并且也不要忘记调用super.paintComponent();
在该方法的开始。没有它,您将阻止代码继续绘制其余组件。见Custom painting in Swing
仍然没有任何显示,因为您尚未为
DrawPanel
声明位置,因此它采用了JFrame
的默认Layout Manager,即BorderLayout
,未指定时的默认位置是CENTER
,并且在同一位置上添加new MainMenu()
时,它将替换DrawPanel
面板,因为同一位置只能存在一个组件。而是尝试将
DrawPanel
放置到CENTER
并将MainMenu
放置到SOUTH
。现在看起来应该像这样:不要忘记通过编写
main
方法将程序放在Event Dispatch Thread (EDT)上,如下所示:public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//Your constructor here
}
});
}
您正在
ActionListener
上实现MainMenu
,但未实现它的方法,请删除它或实现actionPerformed
方法,然后将代码移到b1
动作侦听器中。但是,我强烈建议您也加入Should your class implement ActionListener or use an object of an anonymous ActionListener class您正在玩
MainMenu
的JPanel
可见性,而应该尝试使用CardLayout
或考虑使用JDialog
s。例如,我将制作一个
JDialog
并将JButton
放置在此处,这样它将打开其中绘制有JFrame
的Rectangle
。现在,完成以上输出并遵循所有建议(但#6)的代码是:
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Game {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Game().gui();
}
});
}
public void gui() {
DrawPanel panel = new DrawPanel();
JFrame frame = new JFrame("Test");
frame.add(panel, BorderLayout.CENTER);
frame.add(new MainMenu(), BorderLayout.SOUTH);
frame.setSize(400, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
}
}
class MainMenu extends JPanel {
// GamePanel panel = new GamePanel();
public MainMenu() {
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JButton b1 = new JButton("Start");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipadx = 200;
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
add(b1, c);
}
}
class DrawPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(10, 10, 200, 200);
}
}
如@MadProgrammer的注释中所建议,您还可以覆盖
getPreferredSize()
的DrawPanel
方法,然后调用frame.pack()
:您的
DrawPanel
类现在应如下所示:class DrawPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(10, 10, 200, 200);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
}