簡體   English   中英

JButton從我的JFrame中“擴展”

[英]JButtons “extending” out of my JFrame

對不起我的英語,以及我對編程的無知,這是因為我是新手,而Buttons和JFrame有問題,請幫幫我;)

我將發布問題的打印信息,以及到目前為止我擁有的兩個類的代碼,即GameMenu ,希望你們能解決它,我希望按鈕在灰色面板內繪制。

謝謝。

我的問題的打印

在此處輸入圖片說明 打印

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

    }

}

我不知道您要完成什么,但您沒有正確添加組件:

看着:

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是最難使用的布局,您實際上並不需要它。 我建議您看一下此視覺指南,選擇一種布局並正確學習。 每個LayoutManager的教程都說明了您需要在Constraints參數中添加什么。

之所以調用container.add(component)是因為有時LayoutManager不需要額外的信息(如BoxLayout ),在其他情況下,它僅對使用的LayoutManager使用“默認”約束,這可能不是您所需要的。

例如,主行中的行:

game.janela.add(game);

是正確的,但實際上是調用game.janela.add(game, defaultConstraints); 其中defaultConstraints是JFrame janela的LayoutManager的默認約束值。 因為你沒有顯式地指定它使用JFrames的默認布局框架布局: BorderLayout的 ,並為默認的約束BorderLayout是恆BorderLayout.CENTER

因此,該行實際執行的是:

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

順便說一下,這就是您想要做的。

總結一下:

大多數add調用必須具有兩個參數:組件和約束。 每個LayoutManager使用不同的約束。 您必須知道什么是不為LayoutManager指定約束的方法。 不要開始學習如何將GridMags與GridBagLayout一起正確使用,因為它要復雜得多。

一種以某種方式將組件繪制到圖形對象的快速方法是調用組件類的paint方法。 因此,在您的渲染方法中:

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

但是,您很快就會看到,按照其他答案中所述的方式布局組件時,所有內容都繪制在左上角,並且使所有功能正常工作以達到您希望它們工作的方式會有點復雜。

現在,以下建議是基於我有限的知識而迅速匯總的,因此可能會有更好的方法。

關於菜單類:當我認為最好擴展一個容器(如javax.swing.JPanel )(我假設)以容納這3個按鈕時,您將擴展java.awt.Canvas

接下來將為此應用程序設置適當的布局,該布局將為null。 所以代替:

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

現在將是:

setLayout(null);

這是因為您希望將組件(這些按鈕)塗在另一個組件之上,該組件是擴展Canvas的Game類,而null則允許您這樣做。

由於現在的布局為空,因此您必須指定組件的邊界,這些邊界僅是x和y坐標,並指定其寬度和高度,否則所有內容將分別為0、0、0、0,並且不會顯示任何內容。

所以在游戲的構造函數中

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的Menu中,而不是將它們添加到JFrame(janela)中。 add(startGame); )另外,不要忘記將游戲添加到菜單面板。

它應該像這樣工作:

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

或者,您可以制作自己的窗口小部件工具箱或自定義布局,但我不建議這樣做。 去年我遇到了同樣的問題,但最終轉而使用OpenGL,但無論如何,我希望這對您有所幫助:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM