Java不断添加按钮! -JFrames- [英] Java keeps adding buttons! - JFrames -

查看:63
本文介绍了Java不断添加按钮! -JFrames-的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,所以,我正在尝试使用JFrame制作游戏,当您单击按钮时,会增加钱款并显示更新一些文本(a JLabel).

Alright, so, I am trying to make a game using a JFrame that, when you click a button, adds money, and show update some text(a JLabel).

您看到的,它应该只更新Windows.Money变量并仅在屏幕上显示新变量,但是,它添加了更多按钮.请注意:钱部分工作正常.

You see, it should just update the Windows.Money variable and display ONLY the new variable on the screen, but, it adds more buttons. Please note: The money part works fine.

只是Java不想替换,仅添加即可.

It's just that Java doesn't want to replace, only add.

代码:

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

}

}

我进行了一些要求的编辑,但在将*放到哪里时出现了错误,这些错误全部显示为:

I made some requested edits, and I get errors where I put *, the errors all read:

Cannot make a static reference to the non-static field Window.(anything)

错误点:

for(int i = 0; !*Window.Paused; ) {
        *Window.Money += 2;

            this.wait(1000);

    }

    *Window.Buckets++;
    *Window.BucketCounter = new JLabel("You have: " + *Window.Buckets + "       buckets!");

推荐答案

MVC的简要示例,实际上是Model-View.这是使用 Swing Timer 而不是Threads(不是直接使用)来增加持有在另一个类中的JLabel.它还使用PropertyChangeListener和支持,以将模型状态的更改通知视图(GUI).

Brief example of MVC, well really Model-View. What this does is uses a Swing Timer and not Threads (not directly that is) to increment a JLabel held in a different class. It also uses PropertyChangeListener and support to notify the view (the GUI) of changes in the state of the model.

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()方法的更改做出反应.我用它来启动和停止增加模型的Swing计时器.

Note that I can't use an ActionListener for this to work since an ActionListener only gets activated when the button is released. I'm assuming that you want to accumulate money when the button is pressed, and then stop accumulating when it is released. To do this, you must extract the JButton's model, add a ChangeListener to it, and then react to changes to the model's isPressed() method. I use it to start and stop the Swing Timer that increments the model.

修改
具有更好的MVC(模型-视图-控制)分离的下一次迭代:

Edit
Next iteration with better MVC (model-view-control) separation:

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

}

这篇关于Java不断添加按钮! -JFrames-的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆