简体   繁体   English

JButton从我的JFrame中“扩展”

[英]JButtons “extending” out of my JFrame

Sorry about my English, and my ignorance in programming, its because I'm new at this , and I'm having problem with Buttons and JFrame , please help me ;) 对不起我的英语,以及我对编程的无知,这是因为我是新手,而Buttons和JFrame有问题,请帮帮我;)

I'll post the print of the problem, and the codes of my the two classes I have so far, Game and Menu , hope you guys can solve it, I want the buttons to paint inside the gray panel. 我将发布问题的打印信息,以及到目前为止我拥有的两个类的代码,即GameMenu ,希望你们能解决它,我希望按钮在灰色面板内绘制。

Thanks. 谢谢。

Print of my Problem 我的问题的打印

在此处输入图片说明 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();
    }

}

(MENU CLASS) (菜单类别)

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

    }

}

I don't know what are you trying to accomplish but you are not adding the components correctly: 我不知道您要完成什么,但您没有正确添加组件:

Look at: 看着:

game.janela.setLayout(new GridBagLayout());
game.janela.add(startGame);
game.janela.add(exitGame);
game.janela.add(howToPlay);

This is incorrect, the add method has two arguments, like this: container.add(component, constraints); 这是不正确的, add方法具有两个参数,例如: container.add(component, constraints); your error is not specifying the constraints. 您的错误未指定约束。 The constraints contains all the details to know where in the panel you want to add that component. 约束包含所有详细信息,以了解您要在面板中的哪个位置添加该组件。

For each LayoutManager the Object constraints is diferent. 对于每个LayoutManager ,对象约束是不同的。 For the GridBagLayout the constraints is a GridBagConstraints object. 对于GridBagLayout ,约束是GridBagConstraints对象。

However GridBagLayout is a the most difficult layout to use and you don't really need it. 但是GridBagLayout是最难使用的布局,您实际上并不需要它。 I recommend you to look at this visual guide pick a layout and learn it properly. 我建议您看一下此视觉指南,选择一种布局并正确学习。 The tutorial for each LayoutManager explains what do you need to put in the constraints parameter. 每个LayoutManager的教程都说明了您需要在Constraints参数中添加什么。

The call container.add(component) exists because sometimes the LayoutManager does not need extra information (like the BoxLayout ), in the other cases it just uses the "default" constraints for the LayoutManager in use, which may not be what you need. 之所以调用container.add(component)是因为有时LayoutManager不需要额外的信息(如BoxLayout ),在其他情况下,它仅对使用的LayoutManager使用“默认”约束,这可能不是您所需要的。

For example the line in your main: 例如,主行中的行:

game.janela.add(game);

Is correct, but what it actually does is calling game.janela.add(game, defaultConstraints); 是正确的,但实际上是调用game.janela.add(game, defaultConstraints); where defaultConstraints is the default constraints value for the LayoutManager of the JFrame janela . 其中defaultConstraints是JFrame janela的LayoutManager的默认约束值。 Because you didn't explicitely specify a layout for the frame it is using the default layout for JFrames: BorderLayout , and the default constraints for the BorderLayout is the constant BorderLayout.CENTER . 因为你没有显式地指定它使用JFrames的默认布局框架布局: BorderLayout的 ,并为默认的约束BorderLayout是恒BorderLayout.CENTER

So what that line actually does is: 因此,该行实际执行的是:

game.janela.add(game, BorderLayout.CENTER);

Which incidentally is what you wanted to do. 顺便说一下,这就是您想要做的。

To summarize: 总结一下:

Most calls to add must have two parameters: the component and the constraints. 大多数add调用必须具有两个参数:组件和约束。 Each LayoutManager uses different constraints. 每个LayoutManager使用不同的约束。 You must be aware of what means to not specify the constraints for your LayoutManager. 您必须知道什么是不为LayoutManager指定约束的方法。 Do not start learning about how to properly use LayoutMangers with the GridBagLayout it's much more complex. 不要开始学习如何将GridMags与GridBagLayout一起正确使用,因为它要复杂得多。

A quick way to somehow paint components to a graphics object is calling the paint method of component class. 一种以某种方式将组件绘制到图形对象的快速方法是调用组件类的paint方法。 So in your render method: 因此,在您的渲染方法中:

g.fillRect(0, 0, getWidth(), getHeight());
menu.startGame.paint(g);
...

But as you'll soon see that everything is painted on the top left as components are laid out as said in the other answer and to get everything working to how you want them to work is a bit more complicated. 但是,您很快就会看到,按照其他答案中所述的方式布局组件时,所有内容都绘制在左上角,并且使所有功能正常工作以达到您希望它们工作的方式会有点复杂。

Now the following advice is based on my limited knowledge and was quickly put together so there are probably better ways. 现在,以下建议是基于我有限的知识而迅速汇总的,因此可能会有更好的方法。

About the menu class: You are extending java.awt.Canvas when I think it would be best to extend a container like javax.swing.JPanel as you want it (I assume) to hold those 3 buttons. 关于菜单类:当我认为最好扩展一个容器(如javax.swing.JPanel )(我假设)以容纳这3个按钮时,您将扩展java.awt.Canvas

Next would be to set the appropriate layout for this application, which would be null. 接下来将为此应用程序设置适当的布局,该布局将为null。 So instead of: 所以代替:

game.janela.setLayout(new GridBagLayout());

it would now be: 现在将是:

setLayout(null);

This is because you want components (which are those buttons) to be paint on top of another component which is the Game class that extends Canvas and null allows you to do that. 这是因为您希望将组件(这些按钮)涂在另一个组件之上,该组件是扩展Canvas的Game类,而null则允许您这样做。

Because the layout is now null, you must specify the bounds of the components which are the x and y coordinates alone with the width and the height otherwise everything will just be 0, 0, 0, 0 and nothing would show up. 由于现在的布局为空,因此您必须指定组件的边界,这些边界仅是x和y坐标,并指定其宽度和高度,否则所有内容将分别为0、0、0、0,并且不会显示任何内容。

So in the Game's constructor 所以在游戏的构造函数中

setBounds(0, 0, width * scale, height * scale);

and janela.setPreferredSize(size); janela.setPreferredSize(size); instead of setPreferredSize(size); 而不是setPreferredSize(size);

Back in the Menu class you will have to set the bounds of the buttons like so: 回到Menu类,您将必须像下面这样设置按钮的边界:

Dimensions sgSize = startGame.getPreferredSize();
startGame.setBounds(50, 50, sgSize.width, sgSize.height);

I am using preferred size to get the optimal width and height of the button that was set in the buttons UI (I think). 我正在使用首选大小来获取在按钮UI中设置的按钮的最佳宽度和高度(我认为)。

and add them to the Menu which is now a JPanel instead of adding them to the JFrame(janela). 并将它们添加到现在是JPanel的Menu中,而不是将它们添加到JFrame(janela)中。 ( add(startGame); ) Also, don't forget to add the game to the menu panel. add(startGame); )另外,不要忘记将游戏添加到菜单面板。

and it should work like so: 它应该像这样工作:

( http://i.imgur.com/7cAopvC.png ) (image) http://i.imgur.com/7cAopvC.png )(图像)

Alternatively you could make your own widget toolkit or custom layout, but I wouldn't recommend that. 或者,您可以制作自己的窗口小部件工具箱或自定义布局,但我不建议这样做。 I had this same problem last year but ended up moving to OpenGL but anyway, I hope this has helped :) 去年我遇到了同样的问题,但最终转而使用OpenGL,但无论如何,我希望这对您有所帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM