Java不断添加按钮JFrames-
好的,我正在尝试使用一个Java不断添加按钮JFrames-,java,swing,model-view-controller,jbutton,Java,Swing,Model View Controller,Jbutton,好的,我正在尝试使用一个JFrame制作一个游戏,当你点击一个按钮时,它会增加金钱,并显示更新一些文本(aJLabel) 你看,它应该只更新Windows.Money变量并在屏幕上只显示新变量,但是,它添加了更多的按钮。请注意:金钱部分工作正常 只是Java不想替换,只想添加 代码: package dev.bobdabiulder.classic.main; import javax.swing.JLabel; public class Bucket extends Window{
JFrame
制作一个游戏,当你点击一个按钮时,它会增加金钱,并显示更新一些文本(aJLabel
)
你看,它应该只更新Windows.Money变量并在屏幕上只显示新变量,但是,它添加了更多的按钮。请注意:金钱部分工作正常
只是Java不想替换,只想添加
代码:
package dev.bobdabiulder.classic.main;
import javax.swing.JLabel;
public class Bucket extends Window{
private static final long serialVersionUID = 1L;
public Bucket() throws InterruptedException {
for(int i = 0; !Window.Paused; ) {
Window.Money += 2;
this.wait(1000);
}
Window.Buckets++;
Window.BucketCounter = new JLabel("You have: " + Window.Buckets + " buckets!");
}
}
在Windows
类中
package dev.bobdabiulder.classic.main;
import java.awt.Button;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Window extends JFrame{
public static long Money = 0;
private static final long serialVersionUID = 1L;
private static Thread t1 = new Thread();
private static Thread t2 = new Thread();
private static Thread t3 = new Thread();
private static Thread t4 = new Thread();
private static Thread t5 = new Thread();
public JButton bucket = new JButton("Buy a Bucket!");
public JButton add$ = new JButton("Add Money!");
public JLabel money = new JLabel(Money + "");
public static long Buckets = 0;
public static JLabel BucketCounter = new JLabel("You have: " + Buckets + " buckets!");
public static JPanel buck = new JPanel();
public static boolean Paused = false;
static JFrame jf = new JFrame("Lol!");
//Window Method
public Window() {
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buck.add(bucket);
buck.add(money);
buck.add(add$);
buck.add(BucketCounter);
jf.setSize(500, 500);
jf.add(buck);
bucket.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(bucket)) {
try {
new Bucket();
} catch (Exception e1) {
e1.printStackTrace();
}
}
System.out.println("Action Performed!");
}
});
pack();
}
//End of ActionPerformed
//Start of start()
public static void start() {
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
//
//
//
@SuppressWarnings("deprecation")
public static void stop() {
t1.stop();
t2.stop();
t3.stop();
t4.stop();
t5.stop();
}
}
我做了一些要求的编辑,我把*放在了错误的地方,所有的错误都是:
无法对非静态字段窗口进行静态引用。(任何内容)
错误点:
for(int i = 0; !*Window.Paused; ) {
*Window.Money += 2;
this.wait(1000);
}
*Window.Buckets++;
*Window.BucketCounter = new JLabel("You have: " + *Window.Buckets + " buckets!");
MVC的简单示例,以及真正的模型视图。这样做的目的是使用摆动计时器而不是线程(不是直接使用线程)来增加保存在不同类中的JLabel。它还使用PropertyChangeListener和支持通知视图(GUI)模型状态的更改
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
/**
* http://stackoverflow.com/q/22620807/522444
* http://stackoverflow.com/a/22621767/522444
* @author Pete
*
*/
@SuppressWarnings("serial")
public class ShortMvc extends JPanel {
private JTextField moneyField = new JTextField(10);
private JTextField bucketField = new JTextField(10);
private MoneyModel model = new MoneyModel();
private Timer timer = new Timer(model.getTimerDelay(), new TimerListener());
private JButton moneyButton = new JButton("Add Money");
private JButton bucketButton = new JButton("Add Bucket");
public ShortMvc() {
moneyField.setEditable(false);
moneyField.setFocusable(false);
bucketField.setEditable(false);
bucketField.setFocusable(false);
bucketField.setText(String.valueOf(model.getBuckets()));
add(new JLabel("Money:"));
add(moneyField);
add(moneyButton);
add(new JLabel("Buckets:"));
add(bucketField);
add(bucketButton);
moneyButton.getModel().addChangeListener(new MoneyBtnModelListener());
moneyButton.setMnemonic(KeyEvent.VK_M);
bucketButton.addActionListener(new BucketButtonListener());
bucketButton.setMnemonic(KeyEvent.VK_B);
model.addPropertyChangeListener(new ModelListener());
timer.setInitialDelay(0);
}
private class BucketButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
model.incrementBuckets();
}
}
private class MoneyBtnModelListener implements ChangeListener {
private boolean pressed = false;
@Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
if (pressed == model.isPressed()) {
return;
}
pressed = model.isPressed();
if (pressed) {
timer.start();
} else {
timer.stop();
}
}
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
model.incrementMoney(model.getMoneyIncrementAmount());
}
}
private class ModelListener implements PropertyChangeListener {
private NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();
public ModelListener() {
moneyField.setText(moneyFormat.format(model.getMoney()));
}
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (MoneyModel.MONEY.equals(pcEvt.getPropertyName())) {
moneyField.setText(moneyFormat.format(model.getMoney()));
}
else if (MoneyModel.BUCKETS.equals(pcEvt.getPropertyName())) {
int buckets = model.getBuckets();
bucketField.setText(String.valueOf(buckets));
timer.setDelay(model.getTimerDelay());
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Short Mvc");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ShortMvc());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MoneyModel {
public static final String MONEY = "money";
public static final String BUCKETS = "buckets";
private static final int INIT_TIMER_DELAY = 500;
public static final long MONEY_INCREMENT_AMOUNT = 2L;
private long money = 0L;
private int buckets = 1;
private int timerDelay = INIT_TIMER_DELAY;
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
public void setMoney(long money) {
long oldValue = this.money;
long newValue = money;
this.money = money;
pcSupport.firePropertyChange(MONEY, oldValue, newValue);
}
public long getMoneyIncrementAmount() {
return MONEY_INCREMENT_AMOUNT;
}
public void incrementMoney(long addToMoney) {
long oldValue = this.money;
long newValue = money + addToMoney;
this.money = newValue;
pcSupport.firePropertyChange(MONEY, oldValue, newValue);
}
public long getMoney() {
return money;
}
public void setBuckets(int buckets) {
int oldValue = this.buckets;
int newValue = buckets;
this.buckets = newValue;
timerDelay = INIT_TIMER_DELAY / buckets;
pcSupport.firePropertyChange(BUCKETS, oldValue, newValue);
}
public void incrementBuckets(int incrementAmount) {
int newValue = this.buckets + incrementAmount;
setBuckets(newValue);
}
// increment by one
public void incrementBuckets() {
incrementBuckets(1);
}
public int getBuckets() {
return buckets;
}
public int getTimerDelay() {
return timerDelay;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
请注意,我不能使用ActionListener来实现这一点,因为ActionListener只有在释放按钮时才会被激活。我假设你想在按下按钮时积累金钱,然后在松开按钮时停止积累。为此,您必须提取JButton的模型,向其添加ChangeListener,然后对模型的isPressed()
方法的更改做出反应。我用它来启动和停止增加模型的摆动计时器
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
/**
* http://stackoverflow.com/q/22620807/522444
* http://stackoverflow.com/a/22621767/522444
* @author Pete
*
*/
@SuppressWarnings("serial")
public class ShortMvc extends JPanel {
private JTextField moneyField = new JTextField(10);
private JTextField bucketField = new JTextField(10);
private MoneyModel model = new MoneyModel();
private Timer timer = new Timer(model.getTimerDelay(), new TimerListener());
private JButton moneyButton = new JButton("Add Money");
private JButton bucketButton = new JButton("Add Bucket");
public ShortMvc() {
moneyField.setEditable(false);
moneyField.setFocusable(false);
bucketField.setEditable(false);
bucketField.setFocusable(false);
bucketField.setText(String.valueOf(model.getBuckets()));
add(new JLabel("Money:"));
add(moneyField);
add(moneyButton);
add(new JLabel("Buckets:"));
add(bucketField);
add(bucketButton);
moneyButton.getModel().addChangeListener(new MoneyBtnModelListener());
moneyButton.setMnemonic(KeyEvent.VK_M);
bucketButton.addActionListener(new BucketButtonListener());
bucketButton.setMnemonic(KeyEvent.VK_B);
model.addPropertyChangeListener(new ModelListener());
timer.setInitialDelay(0);
}
private class BucketButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
model.incrementBuckets();
}
}
private class MoneyBtnModelListener implements ChangeListener {
private boolean pressed = false;
@Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
if (pressed == model.isPressed()) {
return;
}
pressed = model.isPressed();
if (pressed) {
timer.start();
} else {
timer.stop();
}
}
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
model.incrementMoney(model.getMoneyIncrementAmount());
}
}
private class ModelListener implements PropertyChangeListener {
private NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();
public ModelListener() {
moneyField.setText(moneyFormat.format(model.getMoney()));
}
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (MoneyModel.MONEY.equals(pcEvt.getPropertyName())) {
moneyField.setText(moneyFormat.format(model.getMoney()));
}
else if (MoneyModel.BUCKETS.equals(pcEvt.getPropertyName())) {
int buckets = model.getBuckets();
bucketField.setText(String.valueOf(buckets));
timer.setDelay(model.getTimerDelay());
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Short Mvc");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ShortMvc());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MoneyModel {
public static final String MONEY = "money";
public static final String BUCKETS = "buckets";
private static final int INIT_TIMER_DELAY = 500;
public static final long MONEY_INCREMENT_AMOUNT = 2L;
private long money = 0L;
private int buckets = 1;
private int timerDelay = INIT_TIMER_DELAY;
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
public void setMoney(long money) {
long oldValue = this.money;
long newValue = money;
this.money = money;
pcSupport.firePropertyChange(MONEY, oldValue, newValue);
}
public long getMoneyIncrementAmount() {
return MONEY_INCREMENT_AMOUNT;
}
public void incrementMoney(long addToMoney) {
long oldValue = this.money;
long newValue = money + addToMoney;
this.money = newValue;
pcSupport.firePropertyChange(MONEY, oldValue, newValue);
}
public long getMoney() {
return money;
}
public void setBuckets(int buckets) {
int oldValue = this.buckets;
int newValue = buckets;
this.buckets = newValue;
timerDelay = INIT_TIMER_DELAY / buckets;
pcSupport.firePropertyChange(BUCKETS, oldValue, newValue);
}
public void incrementBuckets(int incrementAmount) {
int newValue = this.buckets + incrementAmount;
setBuckets(newValue);
}
// increment by one
public void incrementBuckets() {
incrementBuckets(1);
}
public int getBuckets() {
return buckets;
}
public int getTimerDelay() {
return timerDelay;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
编辑
具有更好的MVC(模型-视图-控制)分离的下一次迭代:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
import javax.swing.text.JTextComponent;
/**
* http://stackoverflow.com/q/22620807/522444
* http://stackoverflow.com/a/22621767/522444
* @author Pete
*
*/
public class ShortMvc {
private static void createAndShowGui() {
ShortView view = new ShortView();
MoneyModel model = new MoneyModel();
ShortControl control = new ShortControl(model, view);
control.init();
JFrame frame = new JFrame("Short MVC");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(view.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class ShortView {
private JTextField moneyField = new JTextField(10);
private JTextField bucketField = new JTextField(10);
private JButton moneyButton = new JButton();
private JButton bucketButton = new JButton();
private JPanel mainPanel = new JPanel();
public ShortView() {
moneyField.setEditable(false);
moneyField.setFocusable(false);
bucketField.setEditable(false);
bucketField.setFocusable(false);
mainPanel.add(new JLabel("Money:"));
mainPanel.add(moneyField);
mainPanel.add(moneyButton);
mainPanel.add(new JLabel("Buckets:"));
mainPanel.add(bucketField);
mainPanel.add(bucketButton);
}
public JComponent getMainPanel() {
return mainPanel;
}
public JTextComponent getMoneyField() {
return moneyField;
}
public JTextComponent getBucketField() {
return bucketField;
}
public AbstractButton getMoneyButton() {
return moneyButton;
}
public AbstractButton getBucketButton() {
return bucketButton;
}
}
@SuppressWarnings("serial")
class ShortControl {
private MoneyModel model;
private ShortView view;
private Timer timer;
private MoneyBtnAction moneyBtnAction = new MoneyBtnAction("Add Money", KeyEvent.VK_M);
private BucketButtonAction bucketAction = new BucketButtonAction("Add Buckets", KeyEvent.VK_B);
public ShortControl(MoneyModel model, ShortView view) {
this.model = model;
this.view = view;
timer = new Timer(model.getTimerDelay(), new TimerListener());
}
public void init() {
timer.setInitialDelay(0);
view.getBucketField().setText(String.valueOf(model.getBuckets()));
view.getMoneyButton().setAction(moneyBtnAction);
view.getMoneyButton().getModel().addChangeListener(moneyBtnAction);
view.getBucketButton().setAction(bucketAction);
model.addPropertyChangeListener(new ModelListener());
}
private class BucketButtonAction extends AbstractAction {
public BucketButtonAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
model.incrementBuckets();
}
}
private class MoneyBtnAction extends AbstractAction implements ChangeListener {
private boolean pressed = false;
public MoneyBtnAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
// empty
}
@Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
if (pressed == model.isPressed()) {
return;
}
pressed = model.isPressed();
if (pressed) {
timer.start();
} else {
timer.stop();
}
}
}
private class ModelListener implements PropertyChangeListener {
private NumberFormat moneyFormat = NumberFormat.getCurrencyInstance();
public ModelListener() {
view.getMoneyField().setText(moneyFormat.format(model.getMoney()));
}
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (MoneyModel.MONEY.equals(pcEvt.getPropertyName())) {
view.getMoneyField().setText(moneyFormat.format(model.getMoney()));
}
else if (MoneyModel.BUCKETS.equals(pcEvt.getPropertyName())) {
int buckets = model.getBuckets();
view.getBucketField().setText(String.valueOf(buckets));
timer.setDelay(model.getTimerDelay());
}
}
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
model.incrementMoney(model.getMoneyIncrementAmount());
}
}
}
class MoneyModel {
public static final String MONEY = "money";
public static final String BUCKETS = "buckets";
private static final int INIT_TIMER_DELAY = 500;
public static final long MONEY_INCREMENT_AMOUNT = 2L;
private long money = 0L;
private int buckets = 1;
private int timerDelay = INIT_TIMER_DELAY;
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
public void setMoney(long money) {
long oldValue = this.money;
long newValue = money;
this.money = money;
pcSupport.firePropertyChange(MONEY, oldValue, newValue);
}
public long getMoneyIncrementAmount() {
return MONEY_INCREMENT_AMOUNT;
}
public void incrementMoney(long addToMoney) {
long oldValue = this.money;
long newValue = money + addToMoney;
this.money = newValue;
pcSupport.firePropertyChange(MONEY, oldValue, newValue);
}
public long getMoney() {
return money;
}
public void setBuckets(int buckets) {
int oldValue = this.buckets;
int newValue = buckets;
this.buckets = newValue;
timerDelay = INIT_TIMER_DELAY / buckets;
pcSupport.firePropertyChange(BUCKETS, oldValue, newValue);
}
public void incrementBuckets(int incrementAmount) {
int newValue = this.buckets + incrementAmount;
setBuckets(newValue);
}
// increment by one
public void incrementBuckets() {
incrementBuckets(1);
}
public int getBuckets() {
return buckets;
}
public int getTimerDelay() {
return timerDelay;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
好的,这应该有点帮助。。。缺少计时器,但您可以了解如何管理ActionListeners: 主类
public class WindowInit{
public static void main(String args[]){
WindowHelp wh = new WindowHelp();
}
}
WindowHelp(这个很神奇)
是的,其中一个是编译“WindowInit”并运行该类的主类
对于计时器,请在我实现它时给我一些时间。此代码看起来与按钮无关。但是你的for循环看起来很奇怪。向我们展示
wait()
的功能。另外,给我们一些代码,如果我们尝试的话,这些代码可以编译。根据当前的代码,我仍然不知道发生了什么。这是一种艺术,试图决定要发布多少信息和代码,这是一种你会凭借经验变得更擅长的东西,但试着设身处地为我们着想,那些对你的问题和代码连一点线索都没有的人,试着看看我们可能需要什么来获得线索,然后你就会知道我们需要什么。看起来你依赖的是静态变量,这会让你陷入一堆问题我们不需要任何东西,你想发布一个SSCCE/MCVE/MCTRE,简短,可运行,可以用本地变量中的硬编码值编译我选择重写它。谢谢?@Bobdabiulder:祝你好运,别泄气,继续加油!认真考虑在游戏中使用摇摆计时器。好吧!谢谢你,朋友!你介意为Swing定时器提供一个链接吗?我正在忙着开发新版本。又是这样@Bobdabiulder这里是@Bobdabiulder的链接:我可能试图添加bucket支持。不管是谁,这只是给你一个如何工作的想法。