Groovy list and swingbuilder binding tables

Is there a way to bind data to a list and / or table using the builder builder groovy binding syntax? I could only find simple examples that associate simple properties, such as strings and numbers, with a text box, label, or button text.

+4
source share
3 answers

Looked around and the best I could see was using GlazedLists and not standard Swing lists

http://www.jroller.com/aalmiray/entry/glazedlists_groovy_not_your_regular

+2
source

There is a GlazedList plugin. And this article is very helpful. The Griffin guys swear by the GlazedLists.

+1
source

I just did something like this - it really is not that difficult to do manually. This is still ongoing, but if it helps me, I can give what I have. While it binds data in both directions (Updating data updates the component, edits the table, updates the data and sends a notification to any StringChangeListeners object)

I used a class to define a single row of a table. You create this class to determine the nature of your table. It looks something like this:

class Row { // allows the table to listen for changes and user code to see when the table is edited @Bindable // The name at the top of the column @PropName("Col 1") String c1 @Bindable // In the annotation I set the default editable to "false", here I'll make c2 editable. // This annotation can (and should) be expanded to define more column properties. @PropName(value="Col 2", editable=true) String c2 } 

Note that as soon as the rest of the code is packed into a class, this "Row" class is ONLY the thing that needs to be created to create a new table. You create instances of this class for each row, add them to the table, and you do it completely - no other gui job allows you to get the table in a frame.

This class may include quite a bit more code - I intend to have a stream in it that polls the database and updates the related properties, after which the table instantly receives the changes.

To provide custom column properties, I defined an annotation that looks like this (I plan to add more):

 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface PropName { String value(); boolean editable() default false } 

The rest is the class that builds the table. I save it in a separate class so that it can be reused (by instantiating it with another "Row" class)

NOTE. I scored this when I inserted it so that it would not work without a little work (maybe brackets). He used to include a frame that I removed to just include the table. You need to wrap the table returned from getTable () in the frame.

 public class AutoTable<T> { SwingBuilder builder // This way external code can access the table def values=[] // holds the "Row" objects PropertyChangeListener listener={repaint()} as PropertyChangeListener def AutoTable(Class<T> clazz) { builder = new SwingBuilder() builder.build{ table(id:'table') { tableModel(id:'tableModel') { clazz.declaredFields.findAll{ it.declaredAnnotations*.annotationType().contains(PropName.class)}.each { def annotation=it.declaredAnnotations.find{it.annotationType()==PropName.class } String n=annotation.value() propertyColumn(header:n, propertyName:it.name, editable:annotation.editable()) } } tableModel.rowsModel.value=values } } // Use this to get the table so it can be inserted into a container def getTable() { return builder.table } def add(T o) { values.add(o) o.addPropertyChangeListener(listener) } def remove(T o) { o.removePropertyChangeListener(listener) values.remove(o) } def repaint() { builder.doLater{ builder.table.repaint(); } } } 

Perhaps there is a way to do this without adding / removing, setting up a list with the ability to link, but it seemed more work without a lot of advantages.

At some point, I will probably put the finished class somewhere - if you read this and are still interested, reply in the comment and I will definitely do it sooner rather than later.

0
source

Source: https://habr.com/ru/post/1301661/


All Articles