шпунтованный список и таблицы свингбилдера - PullRequest
4 голосов
/ 18 февраля 2010

Есть ли способ привязать данные к списку и / или таблице, используя синтаксис привязки Groovy Swing Builder? Я мог найти только простые примеры, которые связывают простые свойства, такие как строки и числа, с текстовым полем, надписью или текстом кнопки.

Ответы [ 3 ]

2 голосов
/ 19 февраля 2010

Посмотрел вокруг, и лучшее, что я мог видеть, это использовать GlazedLists вместо стандартных списков Swing

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

1 голос
/ 16 февраля 2011

Имеется плагин GlazedList . И эта статья очень полезна. Ребята из Griffon клянутся GlazedLists.

0 голосов
/ 28 октября 2014

Я только что сделал что-то подобное - это действительно не так сложно сделать вручную. Это все еще в стадии разработки, но если кому-то это поможет, я могу дать то, что имею. Пока что он связывает данные в обоих направлениях (Обновление данных обновляет компонент, редактирование таблицы обновляет данные и отправляет уведомление любому свойству propertyChangeListeners «Row»)

Я использовал класс для определения одной строки таблицы. Вы создаете этот класс, чтобы определить природу вашей таблицы. Это выглядит примерно так:

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
}

Обратите внимание, что после того, как остальная часть кода упакована в класс, этот класс "Row" является ЕДИНСТВЕННОЙ вещью, которую необходимо создать для создания новой таблицы. Вы создаете экземпляры этого класса для каждой строки, добавляете их в таблицу, и все готово - никакой другой графический интерфейс не работает, кроме как поместить таблицу в кадр.

Этот класс может включать в себя немного больше кода - я намереваюсь, чтобы он содержал поток, который опрашивает базу данных и обновляет связанные свойства, тогда таблица должна немедленно принять изменения.

Для обеспечения пользовательских свойств столбца я определил аннотацию, которая выглядит следующим образом (я планирую добавить больше):

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

Остальное - это класс, который строит таблицу. Я храню его в отдельном классе, чтобы его можно было использовать повторно (создав его экземпляр с помощью другого класса "Row")

ПРИМЕЧАНИЕ. Я вырезал это, вставив его, чтобы он не работал без небольшой работы (вероятно, фигурные скобки). Он имел обыкновение включать рамку, которую я удалил, чтобы просто включить таблицу. Вам нужно обернуть таблицу, возвращенную из getTable (), во фрейм.

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();
        }
    }   
}

Вероятно, есть способ сделать это без добавления / удаления, выставив привязываемый список, но это выглядело как большая работа без большой выгоды.

В какой-то момент я, вероятно, где-нибудь выложу готовый класс - если вы прочитали это далеко и все еще заинтересованы, ответьте в комментарии, и я обязательно сделаю это раньше, чем позже.

...