JButtons"扩展"我的JFrame

时间:2014-04-12 18:28:56

标签: java swing jframe jbutton

抱歉我的英语,以及我对编程的无知,因为我是新手,而且我遇到按钮和JFrame的问题,请帮助我;)

我会发布问题的印刷品,到目前为止我的两个班级的代码GameMenu,希望你们能解决它,我想按钮来灰色面板内的油漆。

感谢。

打印我的问题

enter image description here Print

(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);

    }

}

2 个答案:

答案 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的默认布局:BorderLayoutBorderLayout的默认约束是常量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,但无论如何,我希望这有助于:)