按下JButton绘制矩形 [英] Draw Rectangle on pressing JButton
问题描述
我目前正在开发一款小游戏,但是我遇到了一个问题:
我有三个类,第一个是JFrame:
公共类游戏{公共静态void main(String [] args){新的Game().gui();}公共无效gui(){DrawPanel面板= 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来调用菜单,但是问题是(出于测试原因)我想在按下开始"时绘制一个矩形.我尝试了不同的方法,但没有任何反应.
公共类MainMenu扩展了JPanel实现ActionListener{GamePanel面板= new GamePanel();公共MainMenu(){setLayout(new GridBagLayout());GridBagConstraints c =新的GridBagConstraints();JButton b1 =新的JButton("Start");c.fill = GridBagConstraints.HORIZONTAL;c.ipadx = 200;b1.addActionListener(new ActionListener(){@Override公共无效actionPerformed(ActionEvent e){setVisible(false);}});加(b1,c);}}公共类DrawPanel扩展了JPanel{公共无效涂料(图形g){g.drawRect(10,10,200,200);}}
我在您的代码中发现了几个错误:
-
您没有将
DrawPanel
添加到任何内容,因为此行frame.add(panel);
被评论,所以,这引出了下一个问题:
-
您正在覆盖
paint()
方法,而不是 -
别忘了将程序放在通过如下编写您的
main
方法来创建事件调度线程(EDT):public static void main(String [] args){SwingUtilities.invokeLater(new Runnable(){@Override公共无效run(){//这里的构造函数}});}
-
您正在
MainMenu
上实现ActionListener
,但未实现它的方法,请删除它或实现actionPerformed
方法并移动b1
动作监听器中的代码.但是,我强烈建议您使用CardLayout
或考虑使用如@MadProgrammer的注释中所建议,您还可以覆盖
DrawPanel
的getPreferredSize()
方法,然后调用frame.pack()
:您的
DrawPanel
类现在应如下所示:class DrawPanel扩展了JPanel {@Override受保护的void paintComponent(Graphics g){super.paintComponent(g);g.drawRect(10,10,200,200);}@Override公共维度getPreferredSize(){返回新的Dimension(400,300);}}
I am currently working on a little game but I just encountered a problem:
I have three classes, the first one is the 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); } }
Now I have two other classes, one is the mainMenu, currently consisting of just one JButton. I decided to make the menu its own class because later, I want to call the menu by pressing escape, but the problem is that (for testing reasons) I want to draw an rectangle when "start" is pressed. I tried different approaches but nothing happens.
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); } }
解决方案There are several errors I found in your code:
You're not adding your
DrawPanel
to anything because this lineframe.add(panel);
is commented, so, that leads us to the next problem:
You're overriding
paint()
method instead ofpaintComponent()
and also don't forget to callsuper.paintComponent();
at the very beginning of the method. Without it, you're preventing your code to keep painting the rest of the components. See Custom painting in Swing
That still doesn't makes anything appear because you haven't declared a location for your
DrawPanel
and thus it's takingJFrame
's default Layout Manager which isBorderLayout
and it's default location when not specified isCENTER
, and as you're addingnew MainMenu()
to it on the same position it replaces theDrawPanel
panel, since only one component can exist on the same position.Instead try and place the
DrawPanel
to theCENTER
and theMainMenu
to theSOUTH
. It now should look like this:Don't forget to place your program on the Event Dispatch Thread (EDT) by writing your
main
method as follows:public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { //Your constructor here } }); }
You're implementing
ActionListener
onMainMenu
but not implementing it's methods, remove it or implement theactionPerformed
method and move the code inside theb1
action listener to it. However I highly recommend you to take at Should your class implement ActionListener or use an object of an anonymous ActionListener class tooYou're playing with
MainMenu
'sJPanel
visibility, instead you should try using aCardLayout
or consider usingJDialog
s.For example I would make a
JDialog
and place theJButton
there, so it will open theJFrame
with theRectangle
drawn in it.
Now, the code that made the above output and follows all recommendations (but #6) is:
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); } }
As suggested in the comments by @MadProgrammer, you can also override the
getPreferredSize()
method of yourDrawPanel
and then callframe.pack()
:Your
DrawPanel
class should now look like this: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); } }
这篇关于按下JButton绘制矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!