Connecting JComboBox and JTable

I set ComboBoxItem as TableCellRenderer.

My ComboBoxItem is like JcomboBox but it can keep two values.

One of them (Description) it shows to user and the other one (ID)it sends to table.

ComboBoxItem is like JcomboBox(<>Vector).Elements of vector are class Item.

Item has two variables:

ID(int)

Description(String)

The problem is:

Column, where ComboBoxItem set as DefaultCellRenderer keeps ID.

I want ComboBoxItem show appropriate Description for Id form table cell.

Now, this column shows just ID, no appropriate description to this ID.

The situation is:

When I load JTable, I seeID in column where ComboBoxItem is set as DefaultCellRenderer.

When I click on cell from this column, I can get list od Descriptions.

Then ComboBox sends ID of chosen description to Jtable and JTable stores new value.

The problem is that ComboBoxItem does not "see" values in JTable cell.

ComboBoxItem can only send right ID to sell.

I want it to read ID from sell and set option corresponding to ID in cell.

Here is the pict (very small, 92,5 Kb)

http://foto.mail.ru/mail/ice_holod/448/s-450.jpg

Here is the code where I create Jtable:

publicclass TableCreateextends JPanel{

private JTableAdapter jta;

/** Creates a new instance of TableCreate */

public TableCreate(){

super(new GridLayout(1,0));

LoadDriver loaddrv =new LoadDriver ("com.mysql.jdbc.Driver","jdbc:mysql://localhost/Document?","root","");

loaddrv.setNewConnectionToDB();//connection to DB

//creating JTable form TableAbstractModel

/***/this.jta =new JTableAdapter(loaddrv.getAliveConnection());

/***/JTable table =new JTable(jta);

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

table.setPreferredScrollableViewportSize(new Dimension(500,210));

JScrollPane scrollpane =new JScrollPane(table,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

initColumnSizes(table);

//set new renderer for table column

setSheetTypeComboBoxItem(table, table.getColumnModel().getColumn(4),loaddrv.getAllSheetType() );

add(scrollpane);

}

//....and so on.....

And the method (it is in the same class):

publicvoid setSheetTypeComboBoxItem(JTable table, TableColumn SheetTypeIDcolumn,Vector inputvector){

//creating ComboBoxItem values from Vector

ComboBoxItem combobox =new ComboBoxItem(inputvector);

SheetTypeIDcolumn.setCellEditor(new DefaultCellEditor(combobox.getComboBoxItem()));

DefaultTableCellRenderer renderer =new DefaultTableCellRenderer();

renderer.setToolTipText("Press to choose other value");

SheetTypeIDcolumn.setCellRenderer(renderer);

}//setSheetTypeComboBoxItem

So I hope I've explained problem clearly.

[4065 byte] By [Holoda] at [2007-11-26 20:37:00]
# 1

This is a simple example:

import java.awt.Dimension;

import javax.swing.DefaultCellEditor;

import javax.swing.JComboBox;

import javax.swing.JDialog;

import javax.swing.JFrame;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.UIManager;

import javax.swing.table.DefaultTableModel;

public class ComboTableTest {

public static void main(String[] args) {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

JFrame frame = new JFrame();

frame.setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);

DefaultTableModel model = new DefaultTableModel(new String[]{"col1", "col2"}, 0);

JTable table = new JTable(model);

TableItem[] tableItems = new TableItem[] {new TableItem("a", 1), new TableItem("b", 2), new TableItem("c", 2)};

model.addRow(new Object[] {"row1", tableItems[0]});

model.addRow(new Object[] {"row2", tableItems[1]});

JComboBox comboBox = new JComboBox(tableItems);

table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(comboBox));

table.setPreferredScrollableViewportSize(new Dimension(300, 300));

JScrollPane pane = new JScrollPane(table);

frame.getContentPane().add(pane);

frame.pack();

frame.setVisible(true);

} catch (Exception e) {e.printStackTrace();}

}

private static class TableItem {

private String description;

private int id;

public TableItem(String description, int id) {

this.description = description;

this.id = id;

}

public int getID() {

return id;

}

public String toString() {

return description;

}

}

}

Now if you want to get the id you just iterate over the rows and get TableItem for each row using table.getValueAt(row, 1) and then call getID() to get the id.

For example to get the id in col2 row 0:

int id = ((TableItem) table.getValueAt(0, 1)).getID();

Rodney_McKaya at 2007-7-10 1:30:44 > top of Java-index,Desktop,Core GUI APIs...
# 2

> My ComboBoxItem is like JcomboBox but it can keep two values.

> One of them (Description) it shows to user and the other one (ID)it sends to table.

You've already been given a working example on how to do this. See reply 5 in your previous posting:

http://forum.java.sun.com/thread.jspa?threadID=5142759

If you need further help then you need to create a [url http://homepage1.nifty.com/algafield/sscce.html]Short, Self Contained, Compilable and Executable, Example Program[/url] (SSCCE) that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

And don't forget to use the [url http://forum.java.sun.com/help.jspa?sec=formatting]Code Formatting Tags[/url] so the code retains its original formatting.

camickra at 2007-7-10 1:30:44 > top of Java-index,Desktop,Core GUI APIs...
# 3

Unfortunately, I can't produce an example.

I use DB so I do not think It will be convinient for you to install mysql, create db and so on.

But if you can do this, tell me, I will prepare test examples, BD+table+data sql scriprt.

It' too difficult for other person to test my application....((((((

Problem is described on the picture.

I gave link before.

http://foto.mail.ru/mail/ice_holod/448/s-451.jpg

On this picture you can see

step-by-step explanation of problem ans screenshot.

I hope, you will understand my difficulty.

I am not english-speaker, so excuse me, sometimes I write awful sentences and you do not understand them.

The problem is:

In my table I have a column where ComboBoxItem is set as DefaultCellRenderer

(I took everything from example you gave me).

When I load JTable with this column I see ID (numbers)

But I want to see Description corresponded to this ID.

For example, I load table Person to JTable:

Family Name Department ID

SmithJohn 1

Edwards Tom2

column "Department ID" has ComboBoxItem

When I click on cell form this column, I can get list of departments. I have set ComboBoxItem as DefaultCellRenderer there.

But when cell is not "clicked" just ID num is in cells.

I want to see the text.

**********

Look at the picture please. On red background You see my JTable.

It is launched application.

See column SheetTypeID. This columns keeps Id of document type.

As you can see it shows JUST ID numbers.

If I click on this column cell see what happens where background is green.

I can get list of document types, I can choose another one, appropriate ID will be saved.

But I still see only ID

**********

Thank you for your previous example, that was great, I gotexperience

working with it, but I need some more.....

Previous example just gives an opportunity to show list of possible values to user and save Id of chosen value to table and DB.

But it constantly shows numerical value (ID), not String (Description).

Message was edited by:

Holod

Holoda at 2007-7-10 1:30:44 > top of Java-index,Desktop,Core GUI APIs...
# 4

> Unfortunately, I can't produce an example. I use DB...

Did you read the link about a what a SSCCE is?

Did you read my example and execute the code? It does not use a database.

> I hope, you will understand my difficulty. I am not english-speaker...

Which is another reason for writing a SSCCE. If you post code that we can execute then we can see the problem. As I said earlier I don't understant you problem because I've already given you a working example with suggetions that I think should make it work. So show me the code that you are using and how you have changed the code from the example I gave you.

It gets annoying when you don't post your work. Now Rodney has spent time giving you a second example that is virtually identical the example I provided you days ago.

If you really want help, then learn to provide simple examples like we have given you and doen't expect us to do all the work.

camickra at 2007-7-10 1:30:44 > top of Java-index,Desktop,Core GUI APIs...
# 5

Oh..please, do not think that I want you to do all work.

It is very interesting to program, but I am not too experienced with Java.

But I want to be good specialist.

Yes, I've read SSCCE., but I had to think a little bit how to make it.

That is why I gave the first screenshots.

So I found a way how to provide you with small example of my program.

I've took example from SWING TUTORIALS and used there

class Item and class ComboBoxItem

The code:

import java.util.Vector;

import javax.swing.DefaultCellEditor;

import javax.swing.JComboBox;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.ScrollPaneConstants;

import javax.swing.table.AbstractTableModel;

import javax.swing.table.DefaultTableCellRenderer;

import javax.swing.table.TableCellRenderer;

import javax.swing.table.TableColumn;

import java.awt.Component;

import java.awt.Dimension;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JList;

import javax.swing.plaf.basic.BasicComboBoxRenderer;

/**

* TableRenderDemo is just like TableDemo, except that it

* explicitly initializes column sizes and it uses a combo box

* as an editor for the Sport column.

*/

public class TableRenderDemo extends JPanel {

private boolean DEBUG = false;

public TableRenderDemo() {

super(new GridLayout(1,0));

JTable table = new JTable(new MyTableModel());

table.setPreferredScrollableViewportSize(new Dimension(500, 70));

//Create the scroll pane and add the table to it.

JScrollPane scrollPane = new JScrollPane(table,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

//Set up column sizes.

initColumnSizes(table);

//Fiddle with the Sport column's cell editors/renderers.

setUpSportColumn(table, table.getColumnModel().getColumn(2));

//Add the scroll pane to this panel.

add(scrollPane);

}

/*

* This method picks good column sizes.

* If all column heads are wider than the column's cells'

* contents, then you can just use column.sizeWidthToFit().

*/

private void initColumnSizes(JTable table) {

MyTableModel model = (MyTableModel)table.getModel();

TableColumn column = null;

Component comp = null;

int headerWidth = 0;

int cellWidth = 0;

Object[] longValues = model.longValues;

TableCellRenderer headerRenderer =

table.getTableHeader().getDefaultRenderer();

for (int i = 0; i < 5; i++) {

column = table.getColumnModel().getColumn(i);

comp = headerRenderer.getTableCellRendererComponent(

null, column.getHeaderValue(),

false, false, 0, 0);

headerWidth = comp.getPreferredSize().width;

comp = table.getDefaultRenderer(model.getColumnClass(i)).

getTableCellRendererComponent(

table, longValues[i],

false, false, 0, i);

cellWidth = comp.getPreferredSize().width;

if (DEBUG) {

System.out.println("Initializing width of column "

+ i + ". "

+ "headerWidth = " + headerWidth

+ "; cellWidth = " + cellWidth);

}

//XXX: Before Swing 1.1 Beta 2, use setMinWidth instead.

column.setPreferredWidth(Math.max(headerWidth, cellWidth));

}

}

public void setUpSportColumn(JTable table,

TableColumn sportColumn) {

//Set up the editor for the sport cells.

Vector inputvector = new Vector();;

inputvector.addElement( new Item(1, "Snowboarding" ) );

inputvector.addElement( new Item(2, "Rowing" ) );

inputvector.addElement( new Item(3, "Knitting" ) );

inputvector.addElement( new Item(4, "Speed reading" ) );

inputvector.addElement( new Item(5, "Pool" ) );

inputvector.addElement( new Item(5, "None of the above" ) );

ComboBoxItem combobox = new ComboBoxItem(inputvector);

sportColumn.setCellEditor(new DefaultCellEditor(combobox.getComboBoxItem()));

DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();

renderer.setToolTipText("Click to choose new val");

sportColumn.setCellRenderer(renderer);

//Set up tool tips for the sport cells.

}

class MyTableModel extends AbstractTableModel {

private String[] columnNames = {"First Name",

"Last Name",

"Sport",

"# of Years",

"Vegetarian"};

private Object[][] data = {

{"Mary", "Campione",

new Integer(1), new Integer(5), new Boolean(false)},

{"Alison", "Huml",

new Integer (2), new Integer(3), new Boolean(true)},

{"Kathy", "Walrath",

new Integer (3), new Integer(2), new Boolean(false)},

{"Sharon", "Zakhour",

new Integer (4), new Integer(20), new Boolean(true)},

{"Philip", "Milne",

new Integer(5), new Integer(10), new Boolean(false)}

};

public final Object[] longValues = {"Sharon", "Campione",

"None of the above",

new Integer(20), Boolean.TRUE};

public int getColumnCount() {

return columnNames.length;

}

public int getRowCount() {

return data.length;

}

public String getColumnName(int col) {

return columnNames[col];

}

public Object getValueAt(int row, int col) {

return data[row][col];

}

/*

* 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 getValueAt(0, c).getClass();

}

/*

* 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 (col < 2) {

return false;

} else {

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] = 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("--");

}

}

/**

* Create the GUI and show it. For thread safety,

* this method should be invoked from the

* event-dispatching thread.

*/

private static void createAndShowGUI() {

//Create and set up the window.

JFrame frame = new JFrame("TableRenderDemo");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

TableRenderDemo newContentPane = new TableRenderDemo();

newContentPane.setOpaque(true); //content panes must be opaque

frame.setContentPane(newContentPane);

//Display the window.

frame.pack();

frame.setVisible(true);

}

public class ComboBoxItem implements ActionListener{//extends

private JComboBox comboBox;

/** Creates a new instance of ComboBoxItem */

public ComboBoxItem(Vector vectorModel) {

comboBox = new JComboBox(vectorModel);

comboBox.setRenderer(new ItemRenderer());

comboBox.addActionListener(this);

}//ComboBoxItem constructor

public void actionPerformed(ActionEvent e){

JComboBox comboBox =(JComboBox)e.getSource();

Item item =(Item)comboBox.getSelectedItem();

System.out.println("!!!actionPerfomed!!!"+item.getId()+":"+item.getDescription());

}//actionPerfomed

/**returns ID of ComboBox value*/

public int hashCode(){

System.out.println("--HASHCODE--");

int id_of_value;

Item item =(Item)comboBox.getSelectedItem();

return id_of_value=item.getId();

}

public boolean equals(Object obj){

System.out.println("-EQUALS");

boolean returnvalue=false;

Item itemIn = (Item)obj;

Item itemSelected =(Item)comboBox.getSelectedItem();

if(itemIn.equals(itemSelected)){

returnvalue=true;

}

else{

returnvalue=false;

}

return returnvalue;

}

/**returns String of ComboBox value*/

public String toString(){

System.out.println("-TOSTRING-");

String string_of_value;

Item item =(Item)comboBox.getSelectedItem();

//return string_of_value=item.getDescription();

return string_of_value=item.getDescription();

}

public JComboBox getComboBoxItem(){

return this.comboBox;

}

class ItemRenderer extends BasicComboBoxRenderer{

public Component getListCellRendererComponent(

JList list, Object value, int index,

boolean isSelected, boolean cellHasFocus)

{

super.getListCellRendererComponent(list , value, index, isSelected, cellHasFocus);

if (value!=null){

Item item = (Item)value;

setText(item.getDescription());

}//if

return this;

}

}//class ItemRenderer

}//class ComboBoxItem

public class Item {//added public modificator

private int id;

private String description;

public Item(int id, String description){

this.id=id;

this.description=description;

}//item constructor

public int getId(){

return id;

}//getId

public String getDescription(){

return description;

}//getDescription

public String toString(){

String str = new String();

Integer int_id=new Integer(this.id);

str=int_id.toString();

return str;

}//toString

}//Item

public static void main(String[] args) {

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

}

}

Please do not be angry if I made a mistake.

I do not want do all my tasks with help of your hands.

Holoda at 2007-7-10 1:30:44 > top of Java-index,Desktop,Core GUI APIs...
# 6

Well, maybe Rodney and myself don't understand what you are trying to do because you are making the problem more complex than it needs to be.

> Please do not be angry if I made a mistake.

I am frustrated because twice you have been given really simple code to try and understand and play with. Twice you have been told that you don't need to do anything special with the model or renders. Intead you post an example where 90 % of the code is not necessary:

a) Why did you create a new TableModel? The DefaultTableModel as was used in Rodneys examble will do exactly what you need without any special coding.

b) Why did you create a custom renderer. You where told that somply implementing the toString() method correctly will do what you want.

c) Why are you storing an Integer in the TableModel in your sports column? In the example given to you by Rodney and myself we show you how to add a custom object to the model.

d) Why to you have a ComboBoxItem and an Item? Again from both examples we used the same object for adding to the TableModel and the combo box.

So do your testing using Rodney class as the starting point. It is very close to what you want (assuming I understand the question), but not perfect. The code as posted does what I believe you need, however as I mentioned in your first posting I believe you need to implement the equals and hashcode methods to provide the ultimate flexibility.

Make the following changes to Rodneys code:

//TableItem[] tableItems = new TableItem[] {new TableItem("a", 1), new TableItem("b", 2), new TableItem("c", 2)};

//model.addRow(new Object[] {"row1", tableItems[0]});

//model.addRow(new Object[] {"row2", tableItems[1]});

// change 2 to 3 in last item

TableItem[] tableItems = new TableItem[] {new TableItem("a", 1), new TableItem("b", 2), new TableItem("c", 3)};

model.addRow(new Object[] {"row1", tableItems[0]});

model.addRow(new Object[] {"row2", tableItems[1]});

model.addRow(new Object[] {"row3", new TableItem("c", 3)}); // new

a) Now run the code and you will see a, b, c as the values in the three rows in the second column

b) Click on the cell containing the "c". When the combo box opens the value "a" will now be selected. This is because the TableModel contains a TableItem that does not exist in the combo box. For the third row we created a new item rather than adding an item from the array used to build the combo box. Although the data in the TableItem is the same it is not the same TableItem. That is why you need to implement the equals() and hashcode() methods.

You should implement the equals method to return true when the "id" of each TableItem is the same. For the hashcode you should be able to just return the "id" value since we will assume it is unique.

camickra at 2007-7-10 1:30:45 > top of Java-index,Desktop,Core GUI APIs...
# 7

I agree, My questions are too complicated.

Answers:

I try to make a client application that works with MYSQL database.

a) I need to create AbstractTableModel.

I have to override methods GetValueAt(), SetValueAt(), GetColumnCount(), GetRowCount() and so on.

This part I have made. My TableModel interacts with database table perfectly.

b) I took this part of code from your previous example:

http://forum.java.sun.com/thread.jspa?threadID=5142759

Please, see reply #5

The link to your example is:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=613731

c) I have to store integer. My database table has ID field. ID field is int type. with help of this ID I can get record from other table.

I work with relational database.....

I can't make comobox items constant. Values in other table can be changed.

The problem is not INSERT JCOMBOBOX. I have seen tons of examples.

Even SWING TUTORIALS provide such example.

The problem is to keep an items in combobox.

Item consists of 2 values: id and description.

description will be shown to user and combobox sends id

to table (tablemodel will update this id in database table with help of SQL query)

And combobox has to read id from cell and show user description connected with this id

You can see my program, which I gave to you.

When you run it, you see only ID. in Sportcolumn.

When you click cell in Sportcolumn, you get items to choose from combobox.

When you have chosen item you want, you again see new id.

That is not right.

It have to show ONLY description, no ID

All I tell you you can see in my program.

And approximately all code I have taken from your examples.....

Maybe I can't understand something or explain...

did you run my code...?

P.S.

You show manually created data for Table and for ComboBox.

But I get all data from database.

I don't know how many rows I will have.

I don't know how many items will Combobox keep.

Maybe I am very stupid, but I used your examples, I can explain I think every code line, but I can't understand how send id from table cell to combobox and make combobox show description for this id from cell

I give you short explanation of my class which extends AbstractTableModel

I put away unneccessary code.

I left there the most important methods.

And I inserted comments.

Just have a short look and you will understand why I need to make own TableModel.

Each JTable data change I have to transport to Database table.

public class JTableAdapter1 extends AbstractTableModel{

private String tableName ="Sheet";//Name of table from my MYSQL database

//variables for interaction with DB

private Connection connection;

private Statement statement;

private ResultSet resultSet;

private String[]columnNames;//array keeps names of columns from database table

private String[]tableColumnNames = {"ID","Name","Family","Patronymic","DepartmentID"};//array keeps names of column which

//I will show to user. I mean they are names of column of JTable

private Vectorrows = new Vector();

private Vector custExecRow = new Vector();

private ResultSetMetaData metaData;

private int i;

private String t="";

/** Creates a new instance of JTableAdapter */

public JTableAdapter1(Connection con) {

/***First of all I prepare statement***/

statement = connection.createStatement();

executeQuery("SELECT " +

"ID," +

"Name," +

"Family," +

"Patronymic," +

"DepartmentID,"+

" FROM " + this.tableName);

}//constructor

public void executeQuery(String query){

if(connection== null || statement == null){

///EXCEPTION

}

//in this method I get data from database table

//I store this data to Vector rows

fireTableChanged(null);

}//try

catch(SQLException ex){

//EXCEPTION

}

}//executeQuery

public boolean isCellEditable(int row,int column){

if(column>0) return true;

else return false;

}//isCellEditable

//public String getDBColumnName(int column){

public String getColumnName(int column){

return this.columnNames[column];

}

public int getRowCount(){

return this.rows.size();

}

public int getColumnCount(){

return this.columnNames.length;

}

public Object getValueAt(int aRow, int aColumn){

Vector row = (Vector)rows.elementAt(aRow);

return row.elementAt(aColumn);

}

public void setValueAt(Object value, int row, int column){

//Before updating DB table cell we need to update JTable cell

Object val;

val = tbRepresentation(column, value);

Vector dataRow = (Vector)rows.elementAt(row);

dataRow.setElementAt(val,column);

//Now it's time to update DB table

try{

String columnName = getColumnName(column);//getDBColumnName

String query = "UPDATE "

+tableName+

" SET "+columnName+" = "+"'"+dbRepresentation(column,getValueAt(row, column))+"'"+

" WHERE ID = "+dbRepresentation(0,getValueAt(row, 0));

PreparedStatement pstmt = connection.prepareStatement(query);

pstmt.executeUpdate();

}//try

catch(Exception ex){

//EXCEPTION

}//catch

}//setValueAt

public Object tbRepresentation(int column, Object value) throws NumberFormatException{

Object val;

int type;

if(value == null){

return "null";

}//if null

try{

type = metaData.getColumnType(column+1);

}//try

catch (SQLException e){

//EXCEPTION

}//catch

switch(type){

case Types.BIGINT:

return val = new Long(value.toString());

case Types.TINYINT:

case Types.SMALLINT:

case Types.INTEGER:

return val = new Integer(value.toString());

case Types.REAL:

case Types.FLOAT:

case Types.DOUBLE:

case Types.DECIMAL:

return val = new Double(value.toString());

case Types.CHAR:

case Types.BLOB:

case Types.VARCHAR:

case Types.LONGNVARCHAR:

return val = new String(value.toString());

case Types.DATE:

return val = new String(value.toString());

default: return val = new String(value.toString());

}//switch

}//tbRepresentation

public Object dbRepresentation(int column, Object value){

Object val;

int type;

if(value == null){

return "null";

}//if null

try{

type = metaData.getColumnType(column+1);

}//try

catch (SQLException e){

return value.toString();

}//catch

switch(type){

case Types.BIGINT:

return val = new Long(value.toString());

case Types.TINYINT:

case Types.SMALLINT:

case Types.INTEGER:

return val = new Integer(value.toString());

case Types.DECIMAL:

case Types.FLOAT:

case Types.DOUBLE:

return val = new Double(value.toString());

case Types.VARCHAR:

case Types.CHAR:

return val = new String(value.toString());

case Types.DATE:

return val = new String(value.toString());

default: return val = new String(value.toString());

}//switch

}//dbRepresentation

public Object getTableRowAsObject(int num){

return this.rows.get(num);

}

}//class

Message was edited by:

Holod

Holoda at 2007-7-10 1:30:45 > top of Java-index,Desktop,Core GUI APIs...
# 8

> I try to make a client application that works with MYSQL database.

This posting is about creating a SSCCE. We don't care about your final application. We are trying to demonstrate the problem using the simplest code possible. So the database is not important. You can always hard code values for demonstration purposes.

> a) I need to create AbstractTableModel.

No you don't. We are trying to create a SSCCE. Did you see Rodneys example. It uses the DefaultTableModel so there is not custom code to clutter the example.

Even in your real application there is no need to create a custom TableModel.

> b) I took this part of code from your previous example:

As I said in that example and twice in this posting and your other posting on this topic, the easiest solution is to simply provide the correct implementation of the toString() method. If you want to use the custom renderer in your real application, then that fine, but the extra code is unnecessary for the SSCCE you are trying to post.

> c) I have to store integer. My database table has ID field. ID field is int type.

Thats fine. You store a TableItem in the TableModel. When you go to update your backend data base you use the getValueAt(...) method to get the TableItem for the cell. Then you use the getID() method to get the id and that is the value you use in your SQL when you update your database.

> When you click cell in Sportcolumn, you get items to choose from combobox.

> When you have chosen item you want, you again see new id.

>That is not right. It have to show ONLY description, no ID

And that is exactly the way Rodneys example works.

> You show manually created data for Table and for ComboBox. But I get all data from database.

>I don't know how many rows I will have. I don't know how many items will Combobox keep.

It doesn't matter where you get the data from. You just build a Vector of TableItems and then create the combo box using this vector. You can hold an unlimited number of entries in the Vector.

> The problem is to keep an items in combobox. Item consists of 2 values: id and description. description will be shown to user and combobox sends id to table

No. You don't send the ID to the table you send the entire TableItem to the table and the TableItem is stored in the TableModel. At least this is the easiest approach. This approach has already been demonstrated with Rodneys code. Note that no custom code is required to do this, other than implementing the equals() and hashcode() methods as I have already stated.

camickra at 2007-7-10 1:30:45 > top of Java-index,Desktop,Core GUI APIs...
# 9

> a) I need to create AbstractTableModel.

No you don't. We are trying to create a SSCCE. Did you see Rodneys example. It uses the DefaultTableModel so there is not custom code to clutter the example.

Even in your real application there is no need to create a custom TableModel.

Yes of course, I've launched all SSCCE you gave me.

As I said in that example and twice in this posting and your other posting on this topic, the easiest solution is to simply provide the correct implementation of the toString() method. If you want to use the custom renderer in your real application, then that fine, but the extra code is unnecessary for the SSCCE you are trying to post.

Yes, I've read comment. So I've tried "Most flexible approach".

Ok, I will put it into my consederation.

Thats fine. You store a TableItem in the TableModel. When you go to update your backend data base you use the getValueAt(...) method to get the TableItem for the cell. Then you use the getID() method to get the id and that is the value you use in your SQL when you update your database.

But how can I update my database table without overriding setValueAt() ? I can't imagine it.

setValueAt() should do 2actions:

1. update data in table

2. update data in database table.

Yes, Rodney example works perfectly. I've used it too.

Without using DB everything works perfectly.

I see it in your examples.

I understand now, that I do not need to make some custom TableModel.

I can:

1.get data to table from database table

2. get data to combobox (id+description) from database table

I can't:

1. link items in combobox and table data (need to write equals() and hashcode()

2. update changed data in database table.....

So now I have a big chaos in my head....(((((

Please, understand, I do not need just table.

I need to see a refrection of database table in JTable....(((

So now I clearly understand your method.

TableItem is a subclass ob class Object

I can just put it into table row, which consists of Objects

But I do not know how to send data updates to database table without using custom TableModel...((((

I have to work with table actions or what..?

...

I need to combine two parts: data interaction between JTable and database table and comboboxes...

Message was edited by:

Holod

Holoda at 2007-7-10 1:30:45 > top of Java-index,Desktop,Core GUI APIs...
# 10

> But how can I update my database table without overriding setValueAt() ? I can't imagine it.

Well, even if you need to override the setValueAt(...) method you can override the setValueAt() method of the DefaultTableModel. You don't need to write the entire TableModel from scratch.

However, If you need to update an external database whenever a cell is changed then I suggest you use a TableModelListener. You will recieve an event whenever the data in any cell is updated. You then simply get the value from the updated cell and update your database. Here is a simple example of using a TableModelListener:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=566133

> I can't: link items in combobox and table data (need to write equals() and hashcode()

Yes, this is the biggest problem.

a) You need to build your combo box with all the valid TableItems (which consist of the Id and Description)

b) now when you build the table you have a problem. Your SQL query will return an Integer to represent the Id. So you need to write a routine that will read through all the TableItems in the combo box. When you find a TableItem whose Id matches the Integer Id you then add that TableItem to the table instead of adding the Integer value to the table. Actually, using this approach you won't even need to implement the equals() and hashcode() methods as you will be using the actual objects from the combo box.

camickra at 2007-7-10 1:30:45 > top of Java-index,Desktop,Core GUI APIs...
# 11

I think that's enough.

I need time to analyze code and try to involve solutions into my application.

Thank you for your attention, for your wish to help me!

If I would have some more questions I would continue this topic or start another one.

.....09/03/2007....

Finally, I solved this problem!

Yaahoo!

Thank you camickr and Rodney

Excuse me, camickr, I gave all duke stars to Rodney.

I forgot to devide them between you. You both gave me extremely neccessary experience and examples!

Thanks, millions of thanks!

Now code is so easy and short, fantastic!

Seems like before, I was trying to touch my right ear with help of my left leg. But now everything is clear and easy to understand

Message was edited by:

Holod

Message was edited by:

Holod

Holoda at 2007-7-10 1:30:45 > top of Java-index,Desktop,Core GUI APIs...