[英]JButtons “extending” out of my JFrame
對不起我的英語,以及我對編程的無知,這是因為我是新手,而Buttons和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);
}
}
我不知道您要完成什么,但您沒有正確添加組件:
看着:
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.