【问题标题】:Java keeps adding buttons! - JFrames - [closed]Java 不断添加按钮! - JFrames - [关闭]
【发布时间】:2014-03-24 21:19:36
【问题描述】:

好的,所以,我正在尝试使用JFrame 制作游戏,当您单击按钮时,会添加资金并显示更新一些文本(JLabel)。

您看,它应该只更新 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();

}

}

我进行了一些请求的编辑,但我在放置 * 的地方出现错误,错误全部为:

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!");

【问题讨论】:

  • 此代码看起来与按钮无关。但是你的 for 循环看起来很奇怪。向我们展示wait() 的作用。另外,给我们一些代码,如果我们尝试一下,它们会真正编译。
  • 根据当前的代码,我仍然不知道发生了什么。
  • 这是一门艺术,试图决定要发布多少信息和代码,随着经验的积累,你会变得更好,但请试着设身处地为我们着想,不知道的人'对于你的问题和你的代码连一点线索都没有,试着看看我们可能需要什么来获得那个线索,然后你就会知道我们需要什么。
  • 看起来你依赖于静态变量,这会导致你陷入一团糟
  • 我们不需要任何东西,您想要发布一个 SSCCE/MCVE/MCTRE,简短、可运行、可在局部变量中使用硬编码值进行编译

标签: java swing model-view-controller jbutton


【解决方案1】:

MVC 的简单示例,确实是模型视图。这样做是使用 Swing Timer 而不是线程(不是直接)来增加不同类中保存的 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() 方法的更改做出反应。我用它来启动和停止增加模型的 Swing Timer。


编辑
具有更好的 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);
   }

}

【讨论】:

  • 我选择重写这个东西。谢谢?
  • @Bobdabiulder:祝你好运,不要气馁,继续加油!认真考虑在您的游戏中使用 Swing 计时器。
  • 好的!谢谢你,朋友!您介意提供 Swing Timers 的链接吗,我有点忙于开发新版本。又是这样!
  • @Bobdabiulder 这是Timer的链接
  • @Bobdabiulder:也许我尝试添加存储桶支持。 Anywho 这只是为了让您了解它是如何工作的。
【解决方案2】:

好的,这应该有点帮助...缺少 Timer 但您可以了解如何管理 ActionListener:

主类

public class WindowInit{
    public static void main(String args[]){
        WindowHelp wh = new WindowHelp();
    }
}

WindowHelp(这个有魔力)

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.event.*;

public class WindowHelp{
    JButton b1;
    JButton b2;
    JLabel label;
    long money;
    long buckets;
    JFrame jf;
    Timer timer;
    public WindowHelp(){
        money = 0;
        buckets = 0;
        b1 = new JButton("Add buckets");
        b2 = new JButton("Add money");
        label = new JLabel("");
        jf = new JFrame("My Game");
        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                buckets += 2;
                label.setText("Buckets: " + buckets);
            }
        });
        b1.setBounds(50,50,100,30);
        b2.setBounds(200,50,100,30);
        label.setBounds(300,50,200,30);
        jf.add(b1);
        jf.add(b2);
        jf.add(label);
        jf.setSize(500,600);
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

是的,一个是您编译“WindowInit”并运行它的主类。

对于计时器,请在我实现它时给我一些时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2020-06-14
    • 2021-02-18
    相关资源
    最近更新 更多