Есть ли универсальная TableModel, которую мы можем использовать в JTables? - PullRequest
1 голос
/ 06 февраля 2012

Сейчас я изучаю JTables и имею несколько бизнес-объектов, которые я извлекаю из БД с помощью Hibernate + Spring Data JPA .

Мне нравится, что Spring Data JPA обрабатывает всегромоздкая реализация DAL, и мне было интересно, есть ли что-то подобное для TableModel.

В принципе, я хотел бы что-то вроде:

public class GenericTableModel<T> extends AbstractTableModel

И GenericTableModel будет использовать отражение и / или аннотации для просмотра T.

Существует ли что-то подобное?Я надеюсь, что мне не нужно иметь TableModel для каждого объекта, который я хочу отобразить в JTable.

Ответы [ 3 ]

3 голосов
/ 06 февраля 2012

И GenericTableModel будет использовать отражение, чтобы изучить T.

Модель стола делает это.

2 голосов
/ 06 февраля 2012

Я нахожусь в процессе написания библиотеки для разработчиков Swing. Это работа в процессе. Но я сделал то, что вы ищете. Посмотрите на классы в этом пакете:

http://code.google.com/p/swingobjects/source/browse/#git%2FSwingObjects%2Fsrc%2Forg%2Faesthete%2Fswingobjects%2Fview%2Ftable

Для примера использования этого, пожалуйста, взгляните на этот класс - посмотрите на номера строк - 70-85

http://code.google.com/p/swingobjects/source/browse/SwingObjects/src/test/CompTest.java

У меня еще нет документации. Но если вы ничего не выполняете, пожалуйста, оставьте комментарий здесь.

Обновление - Пример кода

import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;

import org.aesthete.swingobjects.annotations.Column;
import org.aesthete.swingobjects.view.table.RowDataBean;
import org.aesthete.swingobjects.view.table.SwingObjTable;
import org.jdesktop.swingx.JXFrame;

public class TableDemo {

    public static void main(String[] args) {

        try {

            //For this demo the Framework need not be initialised.. If you plan on using the entire framework, then
            //its best you initialise it before working on anything...
//          SwingObjectsInit.init("/swingobjects.properties", "/error.properties");

            //Here's the data to show on the table
            final List<Row> rows = new ArrayList<Row>();
            rows.add(new Row("Data 1", "Data 2", "Yes", true));
            rows.add(new Row("Data 3", "Data 4", "No", false));


            //Create the swing table as below.. Provide the Row.class to say that the data in the rows
            // will be from this class
            final SwingObjTable<Row> table = new SwingObjTable<Row>(Row.class);
            table.setData(rows);
            table.setVisibleRowCount(4);

            //Make any column into a combo box by calling the below method.
            //A column can be automatically made into a checkbox, by defining your property in the Row class as a boolean
            table.makeColumnsIntoComboBox(new String[] { "Yes", "No" }, 2);

            //Initialise the frame and show it on the screen
            final JXFrame frame = new JXFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setContentPane(new JScrollPane(table));
            frame.pack();
            frame.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static class Row extends RowDataBean{

        @Column(index=0,name="Column 1",editable=true)
        private String column1;

        @Column(index=1,name="Column 2",editable=true)
        private String column2;

        @Column(index=2,name="Column 3",editable=true)
        private String column3;

        @Column(index=3,name="Column 4",editable=true)
        private boolean column4;

        public Row(String column1, String column2, String column3, boolean column4) {
            super();
            this.column1 = column1;
            this.column2 = column2;
            this.column3 = column3;
            this.column4 = column4;
        }
        public String getColumn1() {
            return column1;
        }
        public void setColumn1(String column1) {
            this.column1 = column1;
        }
        public String getColumn2() {
            return column2;
        }
        public void setColumn2(String column2) {
            this.column2 = column2;
        }
        public String getColumn3() {
            return column3;
        }
        public void setColumn3(String column3) {
            this.column3 = column3;
        }
        public boolean getColumn4() {
            return column4;
        }
        public void setColumn4(boolean column4) {
            this.column4 = column4;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((column1 == null) ? 0 : column1.hashCode());
            result = prime * result + ((column2 == null) ? 0 : column2.hashCode());
            result = prime * result + ((column3 == null) ? 0 : column3.hashCode());
            result = prime * result + (column4 ? 1231 : 1237);
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Row other = (Row) obj;
            if (column1 == null) {
                if (other.column1 != null)
                    return false;
            } else if (!column1.equals(other.column1))
                return false;
            if (column2 == null) {
                if (other.column2 != null)
                    return false;
            } else if (!column2.equals(other.column2))
                return false;
            if (column3 == null) {
                if (other.column3 != null)
                    return false;
            } else if (!column3.equals(other.column3))
                return false;
            if (column4 != other.column4)
                return false;
            return true;
        }
    }
}

Обновление: ответ на запросы в комментариях

1) Таблица может быть вставлена ​​в любой компонент, верно? (JPanel, JScrollPane и т. Д.),

Да. Таблица расширяет JXTable (swingx), который расширяет JTable. Так что его можно разместить внутри любого компонента. Хотя в идеале вы должны поместить его в JScrollPane.

2) У нас есть контроль над именами столбцов? (мое приложение локализовано в нескольких языках)

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

Чтобы использовать l10n - Перед тем, как приступить к написанию кода, обязательно инициализируйте инфраструктуру Swing Objects со строкой ниже. Если вы не предоставите языковой стандарт, будет применяться языковой стандарт по умолчанию.

SwingObjectsInit.init("swingobjects", "application",new Locale("fr", "FR"));

Вам необходимо иметь 2 набора файлов свойств.

1) swingobjects - Это обеспечивает настройки по умолчанию для структуры swingobjects. Файл уже предоставлен в моей кодовой базе. Просто скопируйте и вставьте файл в путь к классу.

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

Тогда, наконец, вместо того, чтобы сказать

 @Column(index=0,name="Column 1",editable=true)
 private String column1;

Вы должны будете использовать:

@Column(index=0,key="test.column1",editable=true)
private String column1;

Измените имя на ключ. Это заставит его читать Resource Bundle и искать свойство test.column1 вместо вашего жестко закодированного имени столбца.

3) Требуется ли SwingObjTable hashCode и равно ли это для реализации?

Равенство и хеш-код требуются, если вы используете Swing Objects Framework полностью. Swing Objects Framework, позволяет вам устанавливать данные для элементов GUI в бине в классе вашей модели - Читать как в MVC . Фреймворк автоматически обновляет графический интерфейс, если значение бина изменилось. Чтобы проверить, действительно ли изменилось значение компонента, ему нужно вызвать метод equals. Следовательно, вам нужно переопределить это. Вы можете заставить Eclipse генерировать это для себя. Или, если вы ничего не используете в фреймворке, просто вызовите оттуда super.equals ().

Просто проверьте / клонируйте git-репо, и вы получите доступ к примеру TableDemo.

git clone https://writetosethu@code.google.com/p/swingobjects/ 
2 голосов
/ 06 февраля 2012

http://java.net/projects/beansbinding/ Позволит вам связывать бизнес-объекты для просмотра компонентов (включая таблицы), если у вас есть методы получения и установки Bean-Style.

...