清除数独表

时间:2013-03-02 15:13:13

标签: java swing methods jbutton sudoku

我正在处理这段代码,可以在

找到

http://pastebin.com/7bCFtUHL

基本上,我想添加一个清除方法(按钮),在解决后清除数独。 我已经尝试制作一个遍历每个单元格的循环并将其置于null但我不完全确定如何完全连接它。我也不确定在哪个类中创建它所以它可以连接到我有另一个按钮的GUI。

编辑: 这是我目前得到的明确方法

public void clearCells(){
    for (int y = 0; y < 9; y++) {
        for (int x = 0; x < 9; x++) {
            cells[y][x] = null;
            cells[y][x].setText("");
        }
    }
}

现在我需要将它附加到另一个类的JButton中,这怎么可能?

我的清除按钮看起来像这样

JButton clear = new JButton("Clear");

clear.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e)
    {
        //Code                    
    }        
    }
);

我需要在actionPerformed方法中添加哪些代码才能将其与我的clearCells方法连接?

1 个答案:

答案 0 :(得分:3)

同样,我会将清晰方法的“肉”放在模型本身中。解决方案的一般形式是:

clear.addActionListener(new ActionListener() {

  public void actionPerformed(ActionEvent e) {
       myModel.clearCells();
  }
});

Model类有一个公共void clearCells()方法,它遍历单元格并清除它们。


编辑1
注意:是的,我确实查看了你的pastebin代码链接,我看到的一个大问题是你的SwingSudokuBoard类扩展了SudokuBoard类,这是滥用继承,而你应该使用 composition 。 SwingSudokuBoard类应该包含一个SudokuBoard对象的实例并在其上调用方法。


编辑2
你问:

  

我不确定我能完全理解你。你希望我在按钮的同一个班级中使用清晰的方法,但是我无法调用单元格。我添加了x.clearCells();而x是什么?我的主要类如SwingSudokuBoard.clearCells(); ?无论如何,如果我添加你说的程序抱怨它想要clearCells方法和单元格是静态的。但是如果我将它们置于静态,我会得到一个NullPointerException。

我认为你需要使用模型 - 视图 - 控制(MVC)模式或它的缩写版本,也许你可以将视图与控件结合起来,因为你的程序很小。我建议你有一个单独的模型类,这里可能是SudokuBoard类,然后是一个视图类,这里可能是SwingSudokuBoard类。视图的控制方法(ActionListeners)将调用模型的clearCells()方法。并且不要在这里使用静态任何


编辑3
你问:

  

我假设这些线条。型号:SudokuBoard;查看:SwingSudokuBoard;控制:SwingSudoKiller。怎么会这样?我在控件中有上面发布的actionListener。其他课程怎么样?由于我假设清晰的方法存在于您想要在SudokuBoard中的模型中,但它无法与那里的单元格连接。

我不是专业人士,也没有接受过正式的编程培训,所以理论是我的弱点之一,但我对MVC的解释是,当模型通知模型时,视图会监听模型并自行更新并且控件侦听视图并通过通知模型来响应视图更改。这种精确的模式有变化,不需要严格遵循字母,但所有这一切的关键是尽可能地在代码中分离出单独的关注点以便“耦合”(直接连接的数量)类)低或“松散”和“内聚”(处理相同问题的代码)高或“紧”。

在你的程序中,我再次使用匿名内部侦听器组合视图和控件,就像你正在做的那样。我有视图/控件,它是SwingSudokuBoard类,将SudokuBoard类的实例保存为类字段,并在SudokuBoard字段上使视图/控件的匿名侦听器调用方法。当我之前做过这样的事情时,我通过给它一个SwingPropertyChangeSupport对象以及公共addPropertyChangeListener(...)removePropertyChangeListener(...)方法给出了被观察的模型支持。然后,视图可以轻松响应模型中的更改。

你说:

  

因为我认为clear方法存在于你希望在SudokuBoard中的模型中,但它无法与那里的单元格连接。

我不确定你的意思。模型保存单元格。也许您不是指模型所拥有的逻辑单元格,而是视图所持有的显示的单元格。该视图将为模型添加一个监听器,并在收到模型更改通知时,将询问模型的数据并使用它来更新可视化单元格。


编辑4
例如:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;

public class OverlySimpleModelView {

   private static void createAndShowGui() {
      Model model = new Model();
      ViewControl viewControl = new ViewControl(model);

      JFrame frame = new JFrame("OverlySimpleModelView");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(viewControl.getMainComponent());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class ViewControl {
   private JPanel mainPanel = new JPanel();
   private JTextField number1Field = new JTextField(5);
   private JTextField number2Field = new JTextField(5);
   private JTextField productField = new JTextField(5);

   private Model model;

   public ViewControl(Model model) {
      this.model = model;
      model.addPropertyChangeListener(new MyPropChngListener());
      productField.setEditable(false);
      productField.setFocusable(false);

      mainPanel.add(number1Field);
      mainPanel.add(new JLabel(" * "));
      mainPanel.add(number2Field);
      mainPanel.add(new JLabel(" = "));
      mainPanel.add(productField);

      CalculateAction calculateAction = new CalculateAction("Calculate", KeyEvent.VK_C);
      mainPanel.add(new JButton(calculateAction));
      number1Field.addActionListener(calculateAction);
      number2Field.addActionListener(calculateAction);
      mainPanel.add(new JButton(new ClearAction("Clear", KeyEvent.VK_L)));
   }

   public JComponent getMainComponent() {
      return mainPanel;
   }

   private class MyPropChngListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
         number1Field.setText(String.valueOf(model.getNumber1()));
         number2Field.setText(String.valueOf(model.getNumber2()));
         productField.setText(String.valueOf(model.calculateProduct()));
      }
   }

   private class CalculateAction extends AbstractAction {

      public CalculateAction(String text, int keyCode) {
         super(text);
         putValue(MNEMONIC_KEY, keyCode);
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         try {
            double number1 = Double.parseDouble(number1Field.getText());
            double number2 = Double.parseDouble(number2Field.getText());

            model.setNumber1(number1);
            model.setNumber2(number2);
         } catch (NumberFormatException e) {
            e.printStackTrace();
         }
      }
   }

   private class ClearAction extends AbstractAction {

      public ClearAction(String text, int keyCode) {
         super(text);
         putValue(MNEMONIC_KEY, keyCode); // to allow buttons a mnemonic letter
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         model.clear();
      }
   }
}

class Model {
   public static final String NUMBERS_CHANGED = "numbers changed";
   private double number1 = 0.0;
   private double number2 = 0.0;
   private SwingPropertyChangeSupport propChngSupport = 
         new SwingPropertyChangeSupport(this);



   public double getNumber1() {
      return number1;
   }

   public double getNumber2() {
      return number2;
   }

   public void clear() {
      setNumber1(0.0);
      setNumber2(0.0);
   }

   // make number1 field a "bound" property, one that notifies listeners if it is changed.
   public void setNumber1(double number1) {      
      Double oldValue = this.number1;
      Double newValue = number1;
      this.number1 = number1;
      propChngSupport.firePropertyChange(NUMBERS_CHANGED, oldValue , newValue);
   }

   // ditto for the number2 field
   public void setNumber2(double number2) {
      Double oldValue = this.number2;
      Double newValue = number2;
      this.number2 = number2;
      propChngSupport.firePropertyChange(NUMBERS_CHANGED, oldValue , newValue);
   }

   public double calculateProduct() {
      return number1 * number2;
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      propChngSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      propChngSupport.removePropertyChangeListener(listener);
   }
}

或者更好,因为它使用了一组数字:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;

public class OverlySimpleModelView {

   private static void createAndShowGui() {
      Model model = new Model(5);
      ViewControl viewControl = new ViewControl(model);

      JFrame frame = new JFrame("OverlySimpleModelView");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(viewControl.getMainComponent());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class ViewControl {
   private JPanel mainPanel = new JPanel();
   private JTextField[] numberFields;
   private JTextField productField = new JTextField(5);

   private Model model;

   public ViewControl(Model model) {
      this.model = model;
      model.addPropertyChangeListener(new MyPropChngListener());
      productField.setEditable(false);
      productField.setFocusable(false);

      CalculateAction calculateAction = new CalculateAction("Calculate", KeyEvent.VK_C);

      numberFields = new JTextField[model.getNumberFieldsLength()];
      for (int i = 0; i < numberFields.length; i++) {
         numberFields[i] = new JTextField("0.0", 5);
         mainPanel.add(numberFields[i]);
         numberFields[i].addActionListener(calculateAction);

         if (i < numberFields.length - 1) {
            mainPanel.add(new JLabel(" + "));
         } else {
            mainPanel.add(new JLabel(" = "));
         }
      }
      mainPanel.add(productField);

      mainPanel.add(new JButton(calculateAction));
      mainPanel.add(new JButton(new ClearAction("Clear", KeyEvent.VK_L)));
   }

   public JComponent getMainComponent() {
      return mainPanel;
   }

   private class MyPropChngListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
         for (int i = 0; i < numberFields.length; i++) {
            numberFields[i].setText(String.valueOf(model.getNumber(i)));
         }
         productField.setText(String.valueOf(model.calculateSum()));
      }
   }

   private class CalculateAction extends AbstractAction {

      public CalculateAction(String text, int keyCode) {
         super(text);
         putValue(MNEMONIC_KEY, keyCode);
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         try {
            double[] numbers = new double[numberFields.length];
            for (int i = 0; i < numbers.length; i++) {
               numbers[i] = Double.parseDouble(numberFields[i].getText());
            }

            model.setNumbers(numbers);
         } catch (NumberFormatException e) {
            e.printStackTrace();
         }
      }
   }

   private class ClearAction extends AbstractAction {

      public ClearAction(String text, int keyCode) {
         super(text);
         putValue(MNEMONIC_KEY, keyCode); // to allow buttons a mnemonic letter
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         model.clear();
      }
   }
}

class Model {
   public static final String NUMBERS_CHANGED = "numbers changed";
   private double[] numbers;
   private SwingPropertyChangeSupport propChngSupport = 
         new SwingPropertyChangeSupport(this);

   public Model(int length) {
      numbers = new double[length];
   }

   public void setNumbers(double[] numbers) {
      double[] oldValue = this.numbers;
      double[] newValue = numbers;
      this.numbers = numbers;
      propChngSupport.firePropertyChange(NUMBERS_CHANGED, oldValue , newValue);

   }

   public double calculateSum() {
      double sum = 0.0;
      for (double number : numbers) {
         sum += number;
      }
      return sum;
   }

   public double getNumber(int i) {
      return numbers[i];
   }

   public int getNumberFieldsLength() {
      return numbers.length;
   }

   public void clear() {
      double[] newNumbers = new double[numbers.length];
      setNumbers(newNumbers);
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      propChngSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      propChngSupport.removePropertyChangeListener(listener);
   }
}