无论我做什么,JLabel都不会露面
我尝试了很多不同的东西试图让JLabel展示,但我不明白为什么它不起作用。我已经尝试过调整它,虽然这不是我想要做的,我已经尝试了其他类,但我更愿意坚持这一个,它开始变得非常令人沮丧。如果您有任何想法,请帮忙。但是请尽量保持简单并且非常清楚地解释,因为我对java仍然很新。我只去了大约三四个月。这是我的代码:
I have tried a ton of different things to try to get the JLabel to show but I don't understand why it is not working. I have tried resizing it, though that is not what i want to do, I have tried other classes, but I would prefer to stick with this one, and it is starting to get really frustrating. If you have any ideas please help. But please try to keep them simple and explain very clearly as I am still quite new to java. I have only been going for about three or four months. Here is my code:
package com.thefallenpaladin;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* Created by darkp_000 on 11/4/2015.
*/
@SuppressWarnings("serial")
public class Game extends JPanel implements KeyListener,MouseListener {
public boolean mainMenu = true;
public int winWidth = 700; //Window Stats
public int winHeight = 600;
public int buttonOneX = 60; // Button Stats
public int buttonOneY = 240;
public int buttonOneW = 100;
public int buttonOneH = 75;
public boolean buttonOne = false;
public int mouseX; // not set because it is set in mouseClicked
public int mouseY;
public static void main(String[] args) {
Game game = new Game();
JFrame window = new JFrame("I hate this");
JLabel onePlayer = new JLabel();
onePlayer.setLocation(0,0/*game.buttonOneX + game.buttonOneX/2,game.buttonOneY + game.buttonOneY/2*/);
window.add(game);
window.setFocusable(true);
window.setResizable(false);
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setSize(700,600); //TODO
window.setVisible(true);
game.requestFocusInWindow();
game.add(onePlayer);
game.addKeyListener(game);
game.addMouseListener(game);
window.setLocationRelativeTo(null);
while(true) { // Main Game loop
onePlayer.setText("One Player");
game.repaint();
game.customUpdate();
}
}
public void customUpdate() {
if(mouseX > buttonOneX && mouseX < buttonOneX+buttonOneX && mouseY > buttonOneY && mouseY < buttonOneY+buttonOneY && mainMenu) {
buttonOne = true;
System.out.print("Starting Game");
}
}
public void paint(Graphics g) {
if(mainMenu) {
g.setColor(Color.CYAN); // Set main menu
g.fillRect(0,0,winWidth,winHeight);
g.setColor(Color.GREEN);
g.fillRect(buttonOneX,buttonOneY,buttonOneW,buttonOneH);
}
if(buttonOne) {
mainMenu = false;
g.setColor(Color.GREEN);
g.fillRect(0,0,winWidth,winHeight);
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
System.out.println(e);
}
public void keyReleased(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
// System.out.println(e);
mouseX = e.getX();
mouseY = e.getY();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
好的,所以你犯了几个基本的错误......
Okay so you've made a couple of basic mistakes...
首先, JLabel onePlayer = new JLabel();
创建一个空标签,没有大小( 0x0
)因为标签默认是透明的,你不会看到它
First, JLabel onePlayer = new JLabel();
creates an empty label, with no size (0x0
) and since labels are transparent by default, you'd not see it
接下来,你已经覆盖了 paint
一个顶级容器( JFrame
),但未能有效地保护涂料链,防止任何子组件被涂漆
Next, you've overridden paint
of a top level container (JFrame
), but failed to honor the paint chain effectively preventing any of the child components from ever getting painted
public void paint(Graphics g) {
if (mainMenu) {
g.setColor(Color.CYAN); // Set main menu
g.fillRect(0, 0, winWidth, winHeight);
g.setColor(Color.GREEN);
g.fillRect(buttonOneX, buttonOneY, buttonOneW, buttonOneH);
}
if (buttonOne) {
mainMenu = false;
g.setColor(Color.GREEN);
g.fillRect(0, 0, winWidth, winHeight);
}
}
所以,如果我删除你的绘画方法并改变 JLabel onePlayer = new JLabel();
to JLabel onePlayer = new JLabel(我是一个标签);
I得到这个输出......
So, if I remove your paint method and change JLabel onePlayer = new JLabel();
to JLabel onePlayer = new JLabel("I'm a label");
I get this output...
...
while (true) { // Main Game loop
onePlayer.setText("One Player");
game.repaint();
game.customUpdate();
}
有可能试图搞砸你的程序,你无法保证什么线程你的 main
方法被调用,你不应该做出假设。
has the potential to try screw up your program, you have no guarantee's in what thread your main
method is been called and you should not make assumptions.
首先创建一个自定义组件,扩展从 JPanel
之类的东西覆盖它的 paintComponent
方法,将自定义绘画放在那里。事实上,你应该为游戏的每个状态设置一个面板(菜单,运行,设置等)。
Start by creating a custom component, extending from something like JPanel
and override it's paintComponent
method, place your custom painting there. In fact, you should have a panel for each state of your game (menu, running, settings, etc).
将这些添加到你的框架中(可能使用 CardLayout
让您可以轻松地在它们之间切换。)
Add these to your frame (probably using a CardLayout
to enable you to easily switch between them)
使用线程
或Swing 计时器
作为主游戏循环,你明确创建一个。
Use either a Thread
or Swing Timer
as a main game loop, one which you create explicitly.
看看在AWT和Swing中绘画,执行自定义绘画,如何使用CardLayout 和如何使用Swing Timers 获取更多细节
Have a look at Painting in AWT and Swing, Performing Custom Painting, How to Use CardLayout and How to use Swing Timers for some more details
作为概念示例......
As a "conceptual" example...
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class AwesomeGame {
public static void main(String[] args) {
new AwesomeGame();
}
public AwesomeGame() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface NavigationController {
public void letsPlay();
}
public class ContentPane extends JPanel implements NavigationController {
private CardLayout cardLayout;
private GamePane gamePane;
public ContentPane() {
cardLayout = new CardLayout();
setLayout(cardLayout);
add(new MenuPane(this), "TheMenu");
add((gamePane = new GamePane()), "TheGame");
cardLayout.show(this, "TheMenu");
}
@Override
public void letsPlay() {
cardLayout.show(this, "TheGame");
gamePane.play();
}
}
public class MenuPane extends JPanel {
public MenuPane(NavigationController navigationController) {
JLabel label = new JLabel("My Super Dupa Awesome Game!");
label.setFont(label.getFont().deriveFont(Font.BOLD, 48));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(label, gbc);
JButton play = new JButton("Play Now!");
play.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
navigationController.letsPlay();
}
});
add(play, gbc);
setBackground(Color.GREEN);
}
}
public class GamePane extends JPanel {
public GamePane() {
setBackground(Color.BLUE);
}
public void play() {
Timer timer = new Timer(500, new ActionListener() {
int count;
@Override
public void actionPerformed(ActionEvent e) {
count++;
if (count % 2 == 0) {
setForeground(Color.BLACK);
} else {
setForeground(Color.RED);
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
String text = "I bet you're blowen away by it's awesomness!";
FontMetrics fm = g2d.getFontMetrics();
int x = (getWidth() - fm.stringWidth(text)) / 2;
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(text, x, y);
g2d.dispose();
}
}
}