• Post Reply Bookmark Topic Watch Topic
  • New Topic

Dynamic GridLayout Paint

 
Jon Parise
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey everyone,

I have a questions regarding a combination of GridLyout, events, paint and threads.

Basically I have some threads that are out there collecting lots of data over the network and storing it into my database. I want the user to be able to see a list of what device's are connected and which aren't I also want them to be able to click a check box by that device's listing to stop logging from it.

So I created an event that encapsulations the connection status. The event goes back up to the top level and I know when things disconnect and reconnect.

My only problem comes in the actual drawing of the list. You see the number of devices can change at any time because the user can add or delete them. So I am attempting to dynamically create the list.

Basically, it is created in the following code:



This works, kinda, but has some issues.

First off, I am updating every device even if just 1 changed, which seems like overkill.

Second, it makes the screen flicker when it updates(probably due to 1)

Third, paint is screwed up somehow. It seems to now want to redraw everything.

I guess what I really need to know is how to access the individual items in the layout and change just the one thats needs changing. Also, for the flicker I thought about turning on Double buffering or paging.

Suggestions would be most appreciated.
 
Brian Cole
Author
Ranch Hand
Posts: 920
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Parise:
Suggestions would be most appreciated.


It sounds like a perfect situation for a 3-column JTable.
 
Jon Parise
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks,

I have never used a JTable, so I pretty much didn't know it existed.

I'll read up on the API about it, it seems like it will do the trick.

I appreciate the suggestion!
 
Brian Cole
Author
Ranch Hand
Posts: 920
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Parise:
I have never used a JTable, so I pretty much didn't know it existed.

I'll read up on the API about it, it seems like it will do the trick.


You will want to create a subclass of AbstractTableModel and override these methods:
getRowCount()
getColumnCount()
getColumnName(int col)
getColumnClass(int col)
isCellEditable(int row, int col)
getValueAt(int row, int col)
setValueAt(Object value, int row, int col)

Have getColumnClass() return Boolean.class for the last column and you will automatically get a checkbox in that column.

When new rows are added call fireTableRowsInserted(firstRow, lastRow) (protected method) on the GUI thread. When values in an existing row change call either fireTableRowsUpdated(row, row) or fireTableCellUpdated(int row, int col).

Add the table to your container with something like
yourContainer.add(new JScrollPane(new JTable(yourTableModel)));

Have fun.
 
Jon Parise
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So far so good.

I have implemented my own TableModel that extends AbstractTableModel. I defined my data as a Vector of Vectors to make it dynamically grow. I know it's ugly but I wanted it to be able to grow.

I have it displaying the check boxes, and I have a very smooth update function to update just the one cell as needed.

Now my only problem is how do I tell when the check box is clicked? I am guessing an event listener would suffice.

This is my TableModel:


How would I add the checkBox event to my program?

Also it is driving me crazy that it is giving me a warning about using unchecked or unsafe operations.

I think this line is the problem:
private Vector<Vector> data = new Vector(cols);

Thanks,

Jon
 
Jon Parise
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think i got it. Is there any reason not to use the following:



It just tells me whether to log the data for that device or not. Appears to be working.

Thanks for all the help.
 
Brian Cole
Author
Ranch Hand
Posts: 920
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Parise:
I think i got it. Is there any reason not to use the following:



Well, it would be much simpler to just detect checkbox manipulation in the setValueAt() method, wouldn't it?
 
Brian Cole
Author
Ranch Hand
Posts: 920
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Parise:
I have implemented my own TableModel that extends AbstractTableModel. I defined my data as a Vector of Vectors to make it dynamically grow. I know it's ugly but I wanted it to be able to grow.


Based on the code in your original post, I'm not sure why you would bother with the Vectors. You've already got your deviceManager, right? If so, it should be pretty simple:

getRowCount() -> return deviceManager.getNumDevices()

getValueAt(int row, int col) -> return deviceManager.getDeviceAt(row).getWhatever() depending on the column

setValueAt(Object value, int row, int col) -> if (col==2) deviceManager.getDeviceAt(row).checkAction() [then fireTableCellUpdated(row, col)]

Also it is driving me crazy that it is giving me a warning about using unchecked or unsafe operations.

I think this line is the problem:
private Vector<Vector> data = new Vector(cols);


Again, I would get rid of the Vectors entirely, but this should dispense with the compiler warnings:
private Vector<Vector<Object>> data = new Vector<Vector<Object>>();

[edit: forgot to address the unchecked or unsafe operations warning]
[ February 11, 2008: Message edited by: Brian Cole ]
 
Jon Parise
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I could probably do it without the Vectors.

Since every time the deviceManager's list of devices is updated I just recreate the whole table anyways.

When the status of a device changes, I simply change that cell though.

It is working great now.

Thanks,

Jon
 
Jon Parise
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The compiler doesn't like

Vector<Vector<Object>> data = new Vector<Vector<Object>>(cols);

I had previously tried that it gives the following error:

C:\Documents and Settings\jparise\Desktop\SmartReports\ModbusTCPProject\src\TrueBlendLogger\CheckboxTableModel.java:25: cannot find symbol
symbol : constructor Vector(java.util.Vector<java.lang.Object>
location: class java.util.Vector<java.util.Vector<java.lang.Object>>
Vector<Vector<Object>> data = new Vector<Vector<Object>>(cols);
 
Brian Cole
Author
Ranch Hand
Posts: 920
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Parise:
The compiler doesn't like

Vector<Vector<Object>> data = new Vector<Vector<Object>>(cols);


We're getting off topic, especially if you aren't even using Vectors anymore, but the problem is the type of cols.

You have fixed things so the types on both sides of the = are the same, but the constructor for Vector<Vector<Object>> takes an argument of (essentially) Collection<Vector<Object>>. You are trying to pass it a bare Vector<Object>.

All these angle brackets are IHMO ugly, but what's nice about them is they do catch type errors like this.

If you want cols to be the lone element of data, then use the zero-arg constructor and then call data.add(cols). If you want something else, do that.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!