|
View previous topic :: View next topic |
Author |
Message |
| VIDEN
| Joined: 02 Oct 2006 | Posts: 55 | : | Location: Germany | Items |
|
Posted: Thu Oct 26, 2006 8:20 am Post subject: |
|
|
After I worked through all sorts of swing-tutorials I looked at the NetBeans GUI Editor tutorials and after that I went throgh a few JTable tutorials.
Well, JTable really seemes to be one of the most complicated swing classes and it took me quite a while to just understand a bit of it.
Now I came to the conclusion that I need the following things:
A custom TableModel
and a custom TableCellEditor
Well these to components really are very complicated and I don't quite understand everything.
The TableCellEditor is only used while the User is editing the cells and verifys the users inputs.
The TableModel Tells the JTable what to write in the cells and can add and delete rows and columns and so on.
Well after I call solve for example and I want to write the values of my new userMatrix into the JTable, how do I do that?
just call TableModel again or will this be done automaticly?
I wrote a custom TableModel class based on an example I found, and it actually works!
Code: | class MyTableModel extends AbstractTableModel {
private boolean DEBUG = true;
private String[] columnNames = {"c0",
"c1",
"c2"};
private Cell [][] data = new Cell[3][3];
int i=0;
public MyTableModel(int boxNum){
for(int r=0;r<3;r++){
for(int c=0;c<3;c++){
data[r][c]=currentBoard.userMatrix.boxes[boxNum].cells[i++];
}
}
}
public int getColumnCount() {
return 3;
}
public int getRowCount() {
return 3;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
if(data[row][col].getValue()==0)
return null;
return new Integer (data[row][col].getValue());
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public Class getColumnClass(int c) {
return Integer.class;
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (data[row][col].isOriginal())
return false;
return true;
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public void setValueAt(Object value, int row, int col) {
if (DEBUG) {
System.out.println("Setting value at " + row + "," + col
+ " to " + value
+ " (an instance of "
+ value.getClass() + ")");
}
data[row][col].num =(Integer) value;
fireTableCellUpdated(row, col);
if (DEBUG) {
System.out.println("New value of data:");
printDebugData();
}
}
private void printDebugData() {
int numRows = getRowCount();
int numCols = getColumnCount();
for (int i=0; i < numRows; i++) {
System.out.print(" row " + i + ":");
for (int j=0; j < numCols; j++) {
System.out.print(" " + data[i][j]);
}
System.out.println();
}
System.out.println("--------------------------");
}
}
} |
But I would like the Original Cell Numbers to be colored blue, but I didn't find a way to manage that
oh and I found this:
http://java.sun.com/docs/books/tutorial/uiswing/components/examples/IntegerEditor.java
It looks like i could just use it like it is to edit my cells.
Greets David |
|
Back to top |
|
|
| VIDEN
| Joined: 02 Oct 2006 | Posts: 55 | : | Location: Germany | Items |
|
Posted: Fri Oct 27, 2006 8:20 am Post subject: |
|
|
Hmm okay I desided to just use one JTable because using 9 makes everything more complicated and the code gets confusing and too large.
So far erverything works. The solve Butten works. Solving given and custom Sudokus.
New works fine too.
But in the moment every Cell is looks the same, and they don't get colored so I'll have to work out a custom TableCellRenderer.
But I still have a little Problem, ererything wokrs fine but I didn't Implement it the way it should be.
These are my action events. After doing the the changes using controller the grid has to be painted new, I call updateTables() but the way I update there isn't really nice. There propybly is a better way but I couldn't find one.
Code: | private void solveActionPerformed(java.awt.event.ActionEvent evt) {
saveTablesToBoard();
Integer val=(Integer) numToSolve.getValue();
controller.solve(currentBoard, val.intValue());
updateTables();
}
private void checkActionPerformed(java.awt.event.ActionEvent evt) {
saveTablesToBoard();
controller.check(currentBoard);
updateTables();
}
private void loadNewActionPerformed(java.awt.event.ActionEvent evt) {
int difficulty=selectDifficulty.getSelectedIndex();
currentBoard= new Board();
if(selectDifficulty.getSelectedIndex()<3)
currentBoard=controller.getNewPuzzle(difficulty);
updateTables();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new SwingGUI().setVisible(true);
}
});
}
private void updateTables(){
if(DEBUG)
currentBoard.userMatrix.print();
gridTableModel= new SwingGUI.MyTableModel();
grid.setModel(gridTableModel);
} |
|
|
Back to top |
|
|
| Jean-Christophe
| Joined: 19 Mar 2006 | Posts: 126 | : | Location: Belgium | Items |
|
Posted: Fri Oct 27, 2006 4:00 pm Post subject: |
|
|
If your make your Board extends from AbstractTableModel and create your JTable view using your Board as TableModel, then it will be simpler IMO.
You can update your view whenever a cell changes with fireTableCellUpdated() or the whole board with fireTableDataChanged(). This would replace your updateTables().
And the other way. You may implement isCellEditable() in your Board to return false for given clues and true for the others. Whenver the user inputs some value in the cell of the JTable, your Board.setValueAt() will be called for editable cells.
If you want to validate the user input, look at InputVerifier. _________________ Jean-Christophe
"When you have eliminated the impossible, whatever remains, however improbable, must be the truth." Sherlock Holmes. |
|
Back to top |
|
|
| VIDEN
| Joined: 02 Oct 2006 | Posts: 55 | : | Location: Germany | Items |
|
Posted: Fri Oct 27, 2006 4:35 pm Post subject: |
|
|
In the meantime I have come much further.
I am using a 9x9 JTable that is colored by an custem CellRenderer, it looks really nice ^^
I already have isCellEditable() implemented, the original cells and solved cells are not editable anymore Board.setValueAt() is than called.
I am using a IntegerCellEditor from SUN, but I'm not quite satisfied with it yes. I'll have to work out a few more things there.
I now have one week off but I think I might keep doing a few thing on the Program
I have a few questions I'll ask you when I keep working on it.
Heres the source
http://viden.vi.funpic.de/Sudoku/Sudkou_VIDEN_v0.32.zip
Greets David |
|
Back to top |
|
|
| VIDEN
| Joined: 02 Oct 2006 | Posts: 55 | : | Location: Germany | Items |
|
Posted: Sun Oct 29, 2006 9:42 pm Post subject: |
|
|
Hey, I need a bit of your help again. I extended my solver so that it counts the possible number of solutions.
But I couldn't test this funktion fully because I had no puzzles to test where I new the exact number of solutions. So do you maby have a few puzzles with like 2-10 solutions so I can see if it works right?
There only was one woth 2 possible solutions on the Page you gave me that Ruud made. but I'd like to have a few more
Thx David |
|
Back to top |
|
|
| VIDEN
| Joined: 02 Oct 2006 | Posts: 55 | : | Location: Germany | Items |
|
Posted: Mon Nov 13, 2006 7:50 am Post subject: |
|
|
Okay, I'm back.
It took me a bit longer cause I had to go to University last week.
I'll do my documentation first and than try to get rid of a few Bugs.
Greets David |
|
Back to top |
|
|
| Pat
| Joined: 06 Sep 2006 | Posts: 128 | : | | Items |
|
Posted: Mon Nov 13, 2006 12:00 pm Post subject: re: multiple answers |
|
|
VIDEN wrote: | I extended my solver so that it counts the possible number of solutions.
But I couldn't test this function fully because I had no puzzles to test where I knew the exact number of solutions.
So do you maybe have a few puzzles with like 2-10 solutions so I can see if it works right?
There only was one woth 2 possible solutions on the Page you gave me that Ruud made.
but I'd like to have a few more |
5 answers:
JPF Code: | . 1 . | . . 6 | . . .
. 5 7 | . 9 . | 2 . .
6 . . | . . 8 | 4 . 5
-------+-------+-------
. 7 . | 4 8 . | . . .
. . . | . . . | . . .
. . . | . . . | 7 . 4
-------+-------+-------
2 4 5 | . . . | . 9 .
. . 9 | . 6 . | . . .
. . . | . 3 . | . 8 . |
JPF Code: | . . . | 2 . 8 | 1 . .
. 4 3 | . . . | . 8 .
. 9 . | . . . | . 5 .
-------+-------+-------
1 . . | . . 6 | 7 . .
. . . | 5 . . | 2 6 .
6 . . | . 2 . | . . .
-------+-------+-------
. 7 . | . . . | . . .
. . . | . 6 . | 9 . .
. . 8 | 9 . 5 | . . 1 |
maria45 Code: | 5 . . | 7 . . | . 1 .
. 6 . | . 4 . | . . 7
. . 3 | . . 2 | . . .
-------+-------+------
. . 4 | 8 . . | 2 . .
. 1 . | . 3 . | . 8 .
2 . . | . . 9 | . . 4
-------+-------+------
. . 8 | 6 . . | 3 . .
. 3 . | . 2 . | . 5 .
9 . . | . . 5 | . . 6 |
JPF Code: | 9 . . | 1 . . | . 7 .
. . 6 | . 4 . | . 8 3
. . . | . . . | . . .
-------+-------+-------
. 7 . | 5 . . | . . .
. . . | . . 3 | . . .
. . . | 9 . . | . 5 4
-------+-------+-------
. 1 5 | . . 2 | 3 4 .
. . 3 | 7 5 . | 2 . .
. 8 . | 6 . . | . . . |
|
|
Back to top |
|
|
| VIDEN
| Joined: 02 Oct 2006 | Posts: 55 | : | Location: Germany | Items |
|
Posted: Tue Nov 14, 2006 2:58 pm Post subject: |
|
|
Thx @ Pat now it counts them out right... went back to the way Jean-Christophe did it in my 0.05 version.
Well I after optimizing and debugging the Programm a bit, I came to the conclusion that I will have to implement changing Digits in my Observe Pattern so that I can make my Board extend the AbstractTableModel as you suggested.
This far, if I set the value of a Cell, all buddies get informed and the cellValue is erased form their Candidate list.
But this only works if the old value was a "0".
If it was something else, the old number has to be restored in the Candidates list, as far as there is no other Cell with the same number.
So practically every Cell will have to check if one of its Buddys has the oldValue as Digit. If yes, everything stays the same, if no the OldValue has to be restored in the Candidate list.
Oh and Cells that already have a Number arne't allowed to add Candidates.
This seemes to be really complicated, do you understand what I mean?
And do you have an idea of how to implement this?
Greets David
Code that will have to be changed:
Method in CELL:
Code: |
public void setValue(int value) {
int oldValue=num;
num=value;
if(value>0) {
candidates.emptySet();
candidates.addBit(value);
}
setChanged();
notifyObservers(num);
} |
Observers Method in HOUSE:
Code: | /**Removes the Number of the Observed Object from the other Cells Canidates */
public void update( Observable o, Object obj ){
Cell cell = (Cell)o;
int v = cell.getValue();
for(int i=0;i<9;i++){
if(cells[i].getRow()==cell.getRow() && cells[i].getColumn()==cell.getColumn())
continue;
cells[i].removeCandidate(v);
}
} |
|
|
Back to top |
|
|
| Jean-Christophe
| Joined: 19 Mar 2006 | Posts: 126 | : | Location: Belgium | Items |
|
Posted: Tue Nov 21, 2006 11:02 am Post subject: |
|
|
I think I understand your problem.
You can do it the way you said.
Maybe it will be easier to implement undo/redo features. _________________ Jean-Christophe
"When you have eliminated the impossible, whatever remains, however improbable, must be the truth." Sherlock Holmes. |
|
Back to top |
|
|
| VIDEN
| Joined: 02 Oct 2006 | Posts: 55 | : | Location: Germany | Items |
|
Posted: Tue Nov 21, 2006 2:43 pm Post subject: |
|
|
Well I found a way to do it and it works, but it just doesn't look so good in my eyes. Propably not the way a good Programmer would do it:
Method in Cell:
Code: | public void setValue(int value) {
oldNum=num; //int variable Cell.oldNum this is whats bothering me to have to add an extra Variable to Cell
num=value;
if(value>0) {
candidates.emptySet();
candidates.addBit(value);
}
if(oldNum!=value){
setChanged();
notifyObservers(num);
}
} |
Method in House
Code: | public void update( Observable o, Object obj ){
Cell cell = (Cell)o;
int v = cell.getValue();
for(int i=0;i<9;i++){
if(cells[i].getRow()==cell.getRow() && cells[i].getColumn()==cell.getColumn())
continue;
cells[i].removeCandidate(v);
}
if(cell.getOldNum()!=0){
for(int i=0;i<9;i++){
if(cells[i].getRow()==cell.getRow() && cells[i].getColumn()==cell.getColumn())
continue;
cells[i].checkCandidate(cell.getOldNum());
}
}
} |
If the oldNum wasnt 0 alle buddies now have to check if this oldNum could be a Candidate for them using the Cell.checkCandidate() Method
Method in Cell
Code: | public void checkCandidate(int candidate){
candidates.addBit(candidate);
HashSet buddies=getBuddies();
Iterator buddiesIter = buddies.iterator();
while(buddiesIter.hasNext()){
Cell c=(Cell)buddiesIter.next();
if(c.getValue()==candidate){
removeCandidate(candidate);
return;
}
}
} |
As I sayed it works fine but isn't really good programming...
I have also made Board to my TableModel now and I verify the user-Input with a KeyEventListener.
I thought about the Generator, but if I want one with different difficulties I will have to implement different solving techniques like naked Singles, hidden Singles ect.
I started off with the naked and hidden Single which are quite easy but since I will have to go to University from December to March I wan't to have a stable, working release till then. So I descidet to use a Sudoku DataBase for now.
I want to use 3 *.txt-Files:
EasyPuzzles.txt / MediumPuzzles.txt / HardPuzzles.txt
The Puzzles are saved in lines like:
000306500800500000010000040900080020000000000040060001050000010000009002006108000
I read them out with
Code: | try {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("EasyPuzzles.txt")));
String line;
while( null != (line = in.readLine()) ) {
Board board= new Board(StringToIntArr(line));
this.addBoard(board, 0);
}
in.close();
} catch( Exception ex ) {
System.out.println( ex );
} |
The only thing missing now are the Puzzles ^^
I'll have to see where to get them from...
Greets David |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
Igloo Theme Version 1.0 :: Created By: Andrew Charron
|