Java 清理数独表
我正在编写这段代码,可以在 基本上,我想添加一个clear方法(按钮),在解决数独问题后清除它。 我试着做一个循环,遍历每个单元格并将其设为null,但我不完全确定如何准确地连接它。我也不确定我必须在哪个类中创建它,以便它可以连接到我有另一个按钮的GUI 编辑: 这是我目前得到的清晰方法Java 清理数独表,java,swing,methods,jbutton,sudoku,Java,Swing,Methods,Jbutton,Sudoku,我正在编写这段代码,可以在 基本上,我想添加一个clear方法(按钮),在解决数独问题后清除它。 我试着做一个循环,遍历每个单元格并将其设为null,但我不完全确定如何准确地连接它。我也不确定我必须在哪个类中创建它,以便它可以连接到我有另一个按钮的GUI 编辑: 这是我目前得到的清晰方法 public void clearCells(){ for (int y = 0; y < 9; y++) { for (int x = 0; x < 9; x++) {
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("");
}
}
}
我需要在actionPerformed方法中添加什么代码来连接我的clearCells方法?同样,我会将clear方法的“肉”放在模型本身中。解决方案的一般形式是:
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
myModel.clearCells();
}
});
其中,模型类将有一个公共的void clearCells()
方法,该方法遍历单元格并清除它们
编辑1
注意:是的,我查看了你的pastebin代码链接,我发现一个大问题是SwingSudokuBoard类扩展了SudokuBoard类,这是对继承的滥用,你应该使用组合。SwingSudokuBoard类应该包含一个SudokuBoard对象的实例,并对其调用方法
编辑2
你问:
我不确定我是否能完全理解你。你想让我在我得到按钮的同一个类中使用clear方法,但是我不能调用单元格。我添加了x.clearCells();当x是什么?我的主课是SwingSudokuBoard.clearCells()?另外,如果我加上你所说的,程序会抱怨它希望clearCells方法和单元格是静态的。但如果我把它们设为静态,就会得到一个NullPointerException 我认为您需要使用模型-视图-控件(MVC)模式或其缩写版本,因为您的程序很小,所以可能需要将视图与控件结合起来。我建议您有一个单独的模型类,这里可能是SudokuBoard类,然后是view类,这里可能是SwingSudokuBoard类。视图的控制方法(ActionListeners)将调用模型的
clearCells()
方法。这里不要使用任何静态的东西
编辑3
你问:
我假设一些东西与这些线。型号:SudokuBoard;视图:SwingSudokuBoard;控制:SwingSudoKiller。那会怎样呢?我会把actionListener贴在上面的控件中。其他课程会是什么样子?因为我假设clear方法存在于你想要在SudokuBoard中的模型中,但是它不能与那里的单元格连接 我不是专业人士,也没有接受过正式的编程培训,因此理论是我的弱点之一,但我对MVC的理解是,视图侦听模型并在模型通知它更改时更新自己,控件侦听视图并通过通知模型来响应视图更改。这种精确的模式有变化,不需要严格遵循,但所有这些的关键是在代码中尽可能多地分离出单独的关注点,以便“耦合”(类之间的直接连接数量)低或“松散”,而“内聚”(处理相同关注点的代码)高或低“紧” 在您的程序中,我再次使用匿名内部侦听器将视图和控件结合起来,就像您所做的那样。我将视图/控件(SwingSudokuBoard类)作为类字段保存SudokuBoard类的实例,并让视图/控件的匿名侦听器在SudokuBoard字段上调用方法以前,我通过给模型一个SwingPropertyChangeSupport对象以及public
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);
}
}
导入java.awt.event.ActionEvent;
导入java.awt.event.KeyEvent;
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入javax.swing.*;
导入javax.swing.event.SwingPropertyChangeSupport;
公共类OverlySimpleModelView{
私有静态void createAndShowGui(){
模型=新模型(5);
ViewControl ViewControl=新ViewControl(模型);
JFrame=新JFrame(“OverlySimpleModelView”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(viewControl.getMainComponent());
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGui();
}
});
}
}
类视图控件{
private JPanel mainPanel=new JPanel();
私有JTextField[]numberFields;
私有JTextField productField=新JTextField(5);
私有模型;
公共视图控件(模型){
this.model=模型;
model.addPropertyChangeListener(新的MyPropChngListener());
productField.setEditable(false);
productField.setFocusable(false);
CalculateAction CalculateAction=新的CalculateAction(“Calculate”,KeyEvent.VK_C);
numberFields=新的JTextField[model.getNumberFieldsLength(
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);
}
}