Assaf
Assaf

Reputation: 1124

Java - drawing a sudoku - How to build the code in the right way?

(A general Question)

I have an assignment in which I have to build a sudoku and I thought about the classes/logic to build it and thought I could use an advice.

I want to use a JFrame and build on it a JPanel with TextFields (the user is supposed to "solve" the sudoku).

I have a class called "DrawSudoku" which draws an empty board. I have to draw an empty board first, so the "user" can type numbers in it. On that board I have to check some logic. So I have to access the textFields themselves.

So far that's all I've done. Now I am thinking about building another class with the "logic" behind the board.

But I've encountered a problem How do I get the JTextFields that exists on the JPanel, from another class?

Can I have separate classes for the Drawing and Logic Behind it?
Thanks!

Upvotes: 0

Views: 484

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

On that board I have to check some logic. So I have to access the textFields themselves.

Not necessarily

How do I get the JTextFields that exists on the JPanel, from another class?

How do you assess the state of any object from another object -- via an accessor or "getter" method.

Can I have separate classes for the Drawing and Logic Behind it?

Not only can you, you absolutely should.

If this were my project I would consider doing the following:

  • First and foremost, create a non-GUI Sudoku model class. This could include:
    • SudokuCellValue enum (name it what you want), an enum that can hold a value from 1 to 9 as well as possibly an EMPTY value (although you could use null to represent this)
    • SudokuCell objects, ones that have boolean editable, and holds a single value to the above enum.
    • SudokuGrid object, a 9 x 9 grid of SudokuCells.
    • A mechanism to hook listeners into the model so that they are notified of changes in state -- i.e., changes in the SudokuCellValue held by one or more SudokuCell objects. The View (the GUI) will be one of the major listeners to this model, and will change its display when the model's state changers.
  • I'd create a View class, meaning the GUI,
    • One that holds a reference to its model (see above)
    • and one that has attached listeners to its model -- I like to use PropertyChangeListeners for this
    • I'd hook it up with a grid of JTextFields,
    • These text fields would use a DocumentFilter to allow the user to either clear the field or enter only 1 through 9 single digit numeric text.
    • Would be enabled for input (or perhaps better -- focusable for input), based on the editable state of the corresponding model cell.
  • I'd create a Controller that would control some of the communication between the view and model.

With this type of set up, outside classes could listen for changes to the model and wouldn't have to have any access directly to the JTextFields of the view.

Upvotes: 2

Keara
Keara

Reputation: 620

You don't need to have access to the text fields themselves if you include public methods in your DrawSudoku class that your logic class can then call. This would be very similar to writing getter and setter methods for private variables. For example, if you wanted your logic class to be able to write the number "6" into a certain square on the board, you could write a method in DrawSudoku like this:

public void setSquareText(String text, int row, int column) {
   // change the appropriate text field here
   textField.setText(text);
}

Then, call this method in your logic class, by making an instance of the drawing class:

DrawSudoku drawer = new DrawSudoku();
drawer.setSquareText("6", 1,1);

Alternatively, you could write a method in DrawSudoku that returns a given JTextField, like this:

public JTextField getTextField(int row, int column){
    // find the appropriate text field, then return it
    return textField;
}

Then, call this method in your logic class to get access to the JTextField, like this:

JTextField textField = drawer.getTextField(1,1);
textField.getText();
textField.setText("6");

Upvotes: 2

Related Questions