Опять же, я бы поставил «мясо» прозрачного метода в самой модели. Общий вид решения будет сделать это:
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
myModel.clearCells();
}
});
Где класс модели будет иметь открытый void clearCells()
метод, который перебирает клетки и очищает их.
Edit 1
Примечание: да я смотрю на ваш код ссылки Pastebin и одна большая проблема, которую я вижу в том, что ваш класс SwingSudokuBoard расширяет класс SudokuBoard, и это неправильное использование наследования, где вы должны быть используя состав вместо. Класс SwingSudokuBoard должен содержать экземпляр объекта SudokuBoard и вызывать методы на нем.
Edit 2
Вы спрашиваете:
Я не уверен, что я могу полностью понять вас. Вы хотите, чтобы у меня был ясный метод в том же классе, что и у меня, но я не могу позвонить в ячейки. Я добавил x.clearCells(); а х - что? Мой основной класс вроде SwingSudokuBoard.clearCells(); ? В противном случае, если я добавлю, что вы говорите, программа жалуется, что хочет, чтобы метод clearCells и ячейки были статическими. Но если я ставил их в статические, я получаю исключение NullPointerException.
Я думаю, что вам нужно использовать шаблон Model-View-Control (MVC) или его сокращенную версию, возможно, такую, где вы комбинируете представление с элементом управления, поскольку ваша программа невелика. Я предлагаю, чтобы у вас был отдельный класс модели, здесь это, вероятно, будет класс SudokuBoard, а затем класс представления, возможно, это класс SwingSudokuBoard. Методы контроля вашего вида (ActionListeners) вызовут метод модели clearCells()
. И не используйте статические что-нибудь здесь.
Edit 3
Вы спрашиваете:
Я полагаю, что-то вместе с этими линиями. Модель: SudokuBoard; Просмотр: SwingSudokuBoard; Управление: SwingSudoKiller. Как это будет продолжаться? У меня будет элемент actionListener, указанный выше в элементе управления. Как выглядят другие классы? Поскольку я предполагаю, что ясный метод лежит в Модели, которую вы хотите находиться в SudokuBoard, но она не может соединяться с ячейками.
Я не профессионал и не получаю официальное обучение программированию, поэтому теория является одной из моих слабых сторон, но моя интерпретация MVC заключается в том, что представление слушает модель и обновляет себя, когда модель уведомляет это изменения и что элемент управления прослушивает представление и реагирует на изменения вида, уведомляя модель. Этот точный шаблон имеет вариации и не требует строгого соответствия буквам, но ключ во всем этом состоит в том, чтобы разделить в своем коде отдельные проблемы как можно больше, чтобы «соединение» (количество прямых соединений между классы) низкий или «свободный» и «сплоченность» (код, который касается тех же самых проблем) является высоким или «плотным».
В вашей программе я снова объединил бы представление и управление с помощью анонимных внутренних слушателей так же, как вы делаете. У меня будет представление/элемент управления, который является классом SwingSudokuBoard, проведет экземпляр класса SudokuBoard в качестве поля класса и вызовет методы анонимного прослушивания view/control в поле SudokuBoard. Когда я это делал раньше, я дал поддержку модели для наблюдения, предоставив ей объект SwingPropertyChangeSupport, а также общедоступные методы и removePropertyChangeListener(...)
. Тогда представление может легко реагировать на изменения в модели.
Вы состояние:
Поскольку я предполагаю, ясный метод лежит в модели, которые вы хотите быть в SudokuBoard, но не может соединиться с клетками там.
Я не уверен, что вы подразумеваете под этим. Модель содержит ячейки. Возможно, вы не имеете в виду логические ячейки, хранящиеся в модели, а отображены. В представлении будет добавлен слушатель к модели, и когда будет уведомлен об изменениях в модели, спросите модель для своих данных и используйте ее для обновления визуализированных ячеек.
Edit 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);
}
}
Пожалуйста, ваши уместную здесь код в вопросе. Если код слишком велик для публикации здесь, значит, он слишком велик, чтобы попросить добровольцев провалиться. –
просто перебираем элементы ** cells ** и устанавливаем пустое значение каждого из них. – Alex
aljesco. Я пробовал это, чтобы прокрутить ячейки в ActionListener для кнопки. Но я не могу достать клетки из этого другого класса. –