Java 将JButton添加到窗口时出现问题
我现在在使用Java 将JButton添加到窗口时出现问题,java,swing,jpanel,jbutton,paintcomponent,Java,Swing,Jpanel,Jbutton,Paintcomponent,我现在在使用JButton时遇到问题。 我的JButton将不会添加到JFrame或JPanel中,并且它似乎正在禁用paintComponent()运行 这是我的JPanel课程: public class BLANKScreen extends JPanel implements Runnable { Thread thread = new Thread(this); public boolean running = false; public static Imag
JButton
时遇到问题。
我的JButton
将不会添加到JFrame
或JPanel
中,并且它似乎正在禁用paintComponent()
运行
这是我的JPanel课程:
public class BLANKScreen extends JPanel implements Runnable {
Thread thread = new Thread(this);
public boolean running = false;
public static ImageIcon greenButton = new ImageIcon("resources/menubuttons/GreenButton.png");
public static JButton mainMenuPlayButton = new JButton("Play!", greenButton);
private int fps;
static BLANKWindow w;
public int scene = 0;
public void run() {
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
scene = 0;
while (running) {
if (scene == 0) {
addMainMenuButtonsOptions();
} else if (scene == 1) {
}
repaint();
frames++;
if (System.currentTimeMillis() - 1000 >= lastFrame) {
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
public BLANKScreen (BLANKWindow w) {
this.w = w;
this.w.addKeyListener(new KeyHandler(this));
this.w.addMouseListener(new MouseHandler(this));
thread.start();
}
public class KeyTyped {
public void keyESC() {
running = false;
}
public void keySpace() {
if (scene == 0) {
scene = 1;
} else if (scene == 1) {
scene = 0;
}
}
}
public class MouseClicked { }
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, this.w.getWidth(), this.w.getHeight());
if (scene == 0) {
int nameLength = g.getFontMetrics().stringWidth("BLANK!");
g.drawString("BLANK!", w.getWidth() / 2 - nameLength / 2, w.getHeight() / 4);
}
}
public void addMainMenuButtonsOptions() {
mainMenuPlayButton.setActionCommand("/mainMenuPlayButton");
mainMenuPlayButton.addActionListener(new ActionHandler());
this.add(mainMenuPlayButton);
System.out.println("ThingHappend");
}
}
和this.add(mainMenuPlayButton)当我说w.add(mainMenuPlayButton)时,code>也不起作用代码>
以下是我的JFrame类:
public class BLANKWindow extends JFrame {
public static void main(String[] args) {
new BLANKWindow();
}
public BLANKWindow() {
new JFrame();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenHeight = screenSize.height;
int screenWidth = screenSize.width;
this.setSize(screenWidth, screenHeight);
this.setTitle("BLANK");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(true);
this.setExtendedState(MAXIMIZED_BOTH);
this.setVisible(true);
BLANKScreen dbs = new BLANKScreen(this);
this.add(dbs);
}
}
出于某种原因,JButton
和paintcompent()
都没有决定加载?@MadProgrammer的评论给出了答案。但是除了严重的线程问题外,您似乎多次向容器添加按钮。据我所知,addMainMenuButtonsOptions
每隔2毫秒调用一次,直到按下一个键。(虽然您没有显示使用类KeyTyped
)的代码,但我假设您已将其绑定到键侦听器?)
一个较小的问题:您是否考虑过在构造函数中使用setBackground
和setOpaque
,而不是手动调用clearRect
正如@Tom所指出的,看起来您使用的是默认布局,因此(多个?)按钮可能会浮到顶部-这就是您想要的吗?基本上,在核心部分,您违反了Swing API的线程,并且似乎对Swing的基本工作方式缺乏了解……欢迎来到危险地带
Swing是单线程的,并且不是线程安全的。这意味着您应该阻止EDT,但也不应该与EDT外部的任何UI组件进行交互或修改
你需要改变你的方法
Swing已经有了一个事件队列、一个处理这些事件的线程、一个事件调度线程,并使用被动绘制算法来更新UI(和布局管理器)
您需要在这些约束条件下工作,以使所有这些都能工作
不要试图在BLANKScreen
类中切换状态,而应该从“菜单面板”和“游戏面板”之类的东西开始
“菜单面板”将向用户显示菜单选项,“游戏面板”将显示游戏,它将具有实际游戏的游戏循环和绘制逻辑
现在,你“可以”让他们一起工作,但我认为你需要先把他们分开…这只会使问题复杂化
然后,您可以使用在它们之间切换。这将使更改可见状态更容易
另请看:
已更新…
面向对象编程的第一条规则——职责分离。一个对象负责它的工作,并且只负责它的工作。如果你发现你的对象正在尝试做更多的事情(比如更新游戏的框架和显示菜单),那么你的想法是错误的(尤其是在这种情况下)
你需要把菜单和游戏分开。游戏有一个更新机制,菜单不在乎,它不需要,它是由核心框架更新的
游戏有自己的用户交互,菜单也有,但它们彼此有不同的含义(鼠标点击菜单会做一些事情,但在游戏中它会做其他事情),所以它们应该分开
菜单和游戏可能彼此都不关心,所以你可以使用某种控制器,它可以控制两者之间的状态并促进通信
这是一个粗略的例子,我通常会花更多的时间构建更好的控制器和模型,但这是为了演示概念的要点,而不是提供一个完全现成的运行解决方案
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestGameMenu {
public static void main(String[] args) {
new TestGameMenu();
}
public TestGameMenu() {
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 MainView());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainView extends JPanel {
private MenuPane menuPane;
private GamePane gamePane;
public MainView() {
setLayout(new CardLayout());
menuPane = new MenuPane();
gamePane = new GamePane();
add(menuPane, "menu");
add(gamePane, "game");
menuPane.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ("play".equalsIgnoreCase(e.getActionCommand())) {
((CardLayout) getLayout()).show(MainView.this, "game");
gamePane.resume();
}
}
});
}
}
public class MenuPane extends JPanel {
private JButton playGame;
public MenuPane() {
setLayout(new GridBagLayout());
playGame = new JButton("Play My Awesome Game!");
playGame.setActionCommand("play");
add(playGame);
}
public void addActionListener(ActionListener listener) {
playGame.addActionListener(listener);
}
public void removeActionListener(ActionListener listener) {
playGame.removeActionListener(listener);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class GamePane extends JPanel {
private Point p;
private int xDelta;
private int yDelta;
private volatile boolean running = true;
private volatile boolean paused = true;
private ReentrantLock lckPause;
private Condition conPause;
public GamePane() {
p = new Point(100, 100);
do {
xDelta = (int)((Math.random() * 10) - 5);
} while (xDelta == 0);
do {
yDelta = (int)((Math.random() * 10) - 5);
} while (yDelta == 0);
lckPause = new ReentrantLock();
conPause = lckPause.newCondition();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (running) {
while (paused) {
lckPause.lock();
try {
conPause.await();
} catch (InterruptedException ex) {
} finally {
lckPause.unlock();
}
}
p.x += xDelta;
p.y += yDelta;
if (p.x < 0) {
p.x = 0;
xDelta *= -1;
} else if (p.x > getWidth()) {
p.x = getWidth();
xDelta *= -1;
}
if (p.y < 0) {
p.y = 0;
yDelta *= -1;
} else if (p.y > getHeight()) {
p.y = getHeight();
yDelta *= -1;
}
repaint();
if (running && !paused) {
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
}
}
}
});
t.start();
}
public void pause() {
if (!paused && running) {
lckPause.lock();
try {
paused = true;
} finally {
lckPause.unlock();
}
}
}
public void resume() {
if (paused && running) {
lckPause.lock();
try {
paused = false;
conPause.signalAll();
} finally {
lckPause.unlock();
}
}
}
public void stop() {
if (running) {
lckPause.lock();
try {
paused = false;
running = false;
conPause.signalAll();
} finally {
lckPause.unlock();
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.fillOval(p.x - 5, p.y - 5, 10, 10);
g2d.dispose();
}
}
}
导入java.awt.CardLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.GridBagLayout;
导入java.awt.Point;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.concurrent.locks.Condition;
导入java.util.concurrent.locks.ReentrantLock;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类TestGameMenu{
公共静态void main(字符串[]args){
新的TestGameMenu();
}
公共测试游戏菜单(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newmainview());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类MainView扩展了JPanel{
私人MenuPane MenuPane;
私人游戏窗格游戏窗格;
公共主视图(){
setLayout(新的CardLayout());
menuPane=新menuPane();
gamePane=新建gamePane();
添加(菜单栏,“菜单”);
添加(游戏窗格,“游戏”);
menuPane.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
if(“play”.equalsIgnoreCase(例如getActionCommand())){
((CardLayout)getLayout()).show(MainView.this,“游戏”);
gamePane.resume();
}
}
});
}
}
公共类MenuPane扩展了JPanel{
私人按钮