抱歉我的英语,以及我对编程的无知,因为我是新手,而且我遇到按钮和JFrame
的问题,请帮助我;)
我会发布问题的印刷品,到目前为止我的两个班级的代码Game
和Menu
,希望你们能解决它,我想按钮来灰色面板内的油漆。
感谢。
打印我的问题
(GAME CLASS)
package br.com.lexo.dagame;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import br.com.lexo.dagame.menu.Menu;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private static int width = 300;
private static int height = width / 16 * 9;
private static int scale = 3;
private static String title = "Da Game";
private Thread thread;
public JFrame janela;
private Menu menu;
private boolean running = false;
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
janela = new JFrame();
menu = new Menu(janela, this);
}
private synchronized void start() {
if (running) return;
running = true;
thread = new Thread(this, "Thread_01");
thread.start();
}
private synchronized void stop() {
if (!running) return;
running = false;
try {
thread.join();
} catch (Exception e) {
e.printStackTrace();
}
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
bs.show();
}
public void update() {
}
public void run() {
while (running){
render();
update();
}
stop();
}
public static void main(String[] args) {
Game game = new Game();
game.janela.add(game);
game.janela.setTitle(title);
game.janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.janela.pack();
game.janela.setLocationRelativeTo(null);
game.janela.setResizable(false);
game.janela.setVisible(true);
game.start();
}
}
(菜单类)
package br.com.lexo.dagame.menu;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import br.com.lexo.dagame.Game;
public class Menu extends Canvas {
private static final long serialVersionUID = 1L;
public boolean inMenu = false;
JButton startGame = new JButton("Começar Jogo");
JButton exitGame = new JButton("Sair do Jogo");
JButton howToPlay = new JButton("Como Jogar");
private Game game;
public Menu(JFrame janela, Game game){
this.inMenu = true;
this.game = game;
game.janela.setLayout(new GridBagLayout());
game.janela.add(startGame);
game.janela.add(exitGame);
game.janela.add(howToPlay);
howToPlay.setEnabled(false);
}
@Override
public void paint(Graphics g) {
super.paint(g);
}
}
答案 0 :(得分:1)
我不知道你想要完成什么,但你没有正确添加组件:
看看:
game.janela.setLayout(new GridBagLayout());
game.janela.add(startGame);
game.janela.add(exitGame);
game.janela.add(howToPlay);
这是不正确的,add
方法有两个参数,如下所示:container.add(component, constraints);
您的错误未指定约束。约束包含所有细节,以了解您要在面板中添加该组件的位置。
对于每个LayoutManager,对象约束是不同的。对于GridBagLayout,约束是GridBagConstraints
对象。
然而,GridBagLayout是最难使用的布局,你并不需要它。我建议你看看这个visual guide选择一个布局并正确学习它。每个LayoutManager的教程解释了您需要在约束参数中添加什么。
调用container.add(component)
存在是因为有时LayoutManager不需要额外的信息(如BoxLayout),在其他情况下它只使用正在使用的LayoutManager的“默认”约束,这可能是不是你需要的。
例如,您的主要行:
game.janela.add(game);
是正确的,但它实际上做的是调用game.janela.add(game, defaultConstraints);
,其中defaultConstraints
是JFrame janela
的LayoutManager的默认约束值。因为您没有明确指定框架的布局,所以它使用JFrame的默认布局:BorderLayout,BorderLayout
的默认约束是常量BorderLayout.CENTER
。
那条线实际上是做什么的:
game.janela.add(game, BorderLayout.CENTER);
顺便说一句,你想做什么。
总结:
对add
的大多数调用必须有两个参数:组件和约束。每个LayoutManager使用不同的约束。您必须知道不指定LayoutManager约束的方法。不要开始学习如何正确使用LayoutMangers GridBagLayout
它会更复杂。
答案 1 :(得分:-1)
以某种方式将组件绘制到图形对象的快速方法是调用组件类的paint
方法。所以在你的渲染方法中:
g.fillRect(0, 0, getWidth(), getHeight());
menu.startGame.paint(g);
...
但是你很快就会看到所有内容都涂在左上方,因为组件的布局正如另一个答案所说的那样,并且让一切工作变得有点复杂。
现在,以下建议是基于我有限的知识,并且很快被放在一起,所以可能有更好的方法。
关于菜单类:
您正在扩展java.awt.Canvas
,我认为最好像javax.swing.JPanel
那样扩展容器(我假设)来保存这3个按钮。
接下来将为此应用程序设置适当的布局,该布局为null。所以而不是:
game.janela.setLayout(new GridBagLayout());
现在是:
setLayout(null);
这是因为您希望组件(这些按钮)在另一个组件上绘制,该组件是扩展Canvas的Game类,而null允许您这样做。
因为布局现在为null,所以必须仅使用宽度和高度指定x和y坐标的组件边界,否则一切都只有0,0,0,0,并且不显示任何内容。
所以在Game的构造函数中
setBounds(0, 0, width * scale, height * scale);
和janela.setPreferredSize(size);
代替setPreferredSize(size);
返回Menu类,您必须设置按钮的界限,如下所示:
Dimensions sgSize = startGame.getPreferredSize();
startGame.setBounds(50, 50, sgSize.width, sgSize.height);
我使用首选尺寸来获得按钮UI中设置的按钮的最佳宽度和高度(我认为)。
并将它们添加到菜单中,该菜单现在是JPanel,而不是将它们添加到JFrame(janela)。 (add(startGame);
)另外,不要忘记将游戏添加到菜单面板。
它应该像这样工作:
(http://i.imgur.com/7cAopvC.png)(图片)
或者你可以制作自己的widget工具包或自定义布局,但我不建议这样做。我去年遇到了同样的问题,但最终转向OpenGL,但无论如何,我希望这有助于:)