Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Swing бесконечный getConnection() :) / 13 сообщений из 13, страница 1 из 1
29.04.2015, 10:16
    #38948206
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Свинг тут в общем-то ни причем, я думаю, но мало ли.
Суть вопроса:
Есть две примерно таких таблицы, одна с пользователями Users
id
name

Вторая с заявками, ну или с документами Docs
id
user_id
nameDoc

коннекчусь к БД через стандартную:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 public Connection getDBConnection() {
        try {
            Class.forName(DB_DRIVER);
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
        }
        try {
            dbConnection = DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
            System.out.println("getConnection: Ok");
            return dbConnection;
        } catch (SQLException e) {
            System.out.println(e);
        }
        return dbConnection;
    }



Создаю модель таблицы, где будут отображаться список документов. В одном из столбцов нужно вывести не user_id а его name из таблицы Users
Делаю так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
public String getUsersVisibleNameById(Integer id) {
        String sql = "select visibleName from Users where id = " + id;
        String visibleName = "";
        try {
            con = phoenixDatabase.getDBConnection();
            pstmt = con.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                visibleName = rs.getString("visibleName");
            }
            return visibleName;
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            try {
                if (con != null) {
                    con.close();
                }
                if (rs != null) {
                    rs.close();
                }
                if (pstmt != null) {
                    pstmt.close();
                }
            } catch (Exception ignore) {
            }
        }
        return null;
    }



В итоге получаю в output'е бесконечный вывод из System.out.println("getConnection: Ok");
....getConnection: Ok
getConnection: Ok
getConnection: Ok....


В модели прописано примерно следующее:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
@Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Doc doc = docs[rowIndex];
        switch (columnIndex) {
            case 0:
                return doc.getId();
            case 1:
                return doc.getNumber();
            case 2:
                return up.getUsersVisibleNameBydoc.getUsersId());
//                return "";
            case 3:
...
Рейтинг: 0 / 0
29.04.2015, 10:37
    #38948232
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
1) getValueAt вызывается для каждой ячейки. А значит для каждой строки. А значит, если у вас строк у модели много, то и метод вызовется множество раз.
А ещё он вызывается множество раз просто чтобы перерисовать таблицу.
2) Способ реализации getDBConnection у вас самый медленный. Подключите Apache Commons DBCP - примеров в инете навалом. И используйте получение соединения через DataSource.
3) В целом архитектура крайне не удачна и не продуманна.

Вам нужна промежуточная модель между Swing и базой данных. Туда нужно вычитать данные для отображения, чтобы быстро их читать из TableModel, например.

4) Обращение к SQL базе, это относительно дорогостоящая операция. Если вы будете выполнять все запросы из Event Dispatch Thread, то ваш UI будет предельно тормозным. Из чего вы сделаете ошибочный вывод, что это Swing такой медленный.

Работать с БД нужно через параллельные потоки. Для этого в Swing существует SwingWorker. Который в фоновом потоке произведет медленную операцию. А затем вычитанные данные поможет быстро отобразить синхронно в EDT.

Иначе UI будет просто замораживаться на каждый SQL запрос. А в вашем случае даже в два раза дольше, так как DriverManager.getConnection тоже очень дорогая операция.
...
Рейтинг: 0 / 0
29.04.2015, 10:44
    #38948247
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Blazkowicz,

В очередной раз Спасибо :)
Буду разбираться.

Для понимая процесса прописал в модели следующее:
case 2:
// return up.getUsersVisibleNameById(request.getUsersId());
System.out.println("show user id");
return "";

и получил в output тот же бесконечный вывод "show user id" :)
...
Рейтинг: 0 / 0
29.04.2015, 10:55
    #38948262
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Nixic,

Thread.dumpStacktrace() поможет понять откуда происходят все вызовы.
Повторяю - метод getValue() дергается множество раз на каждую перерисовку таблицы. Для каждой ячейки. Если у вас перерисовка происходит в бесконечном цикле, возможно вы где-то напхали лишних repaint/invalidate/updateUI методов.
...
Рейтинг: 0 / 0
29.04.2015, 12:43
    #38948469
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Nixic,

Ещё изучите try with resources.
...
Рейтинг: 0 / 0
29.04.2015, 13:14
    #38948520
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Спасибо, занялся этим :)

Продолжаю эксперементировать с jTable.
Модель у меня экстендит AbstractTableModel. Пробовал поставить DefaultTableModel. результат тот же, а именно:

в тот же самый case поставил счетчик, чтобы i++ чтобы видеть сколько раз запросится
getValueAt(...) {}
в case 2:

За 7 минут перевалило за 100 000. Выключил.
Убрал все вызовы модели с полей для фильтрации данных, оставил только один вызов в конструкторе JInternalFrame

Я не понимаю, зачем она всё время дергает этот метод пока запущена...

Пока писал это сообщение, нашел тему, где объясняется это поведение :
You are causing the endless loop in the model.
You're calling setValueAt() from getValueAt().
Your implementation of setValueAt() triggers fireTableCellUpdated. This triggers getValueAt(). And the loop repeats.


и предлагается такой выход:

Add some static counter in your class, initialize to 0.
Then in one of these methods which you ntoed, increment the
counter each time the method is called. Once the counter
reaches value of say 20 or 30, then throw a new
RuntimeException("TEST") in this method.


Но, правильно ли оно? Как-то оно не особо приглядное...

А по поводу " try with resources" вот эта статья подойдет для изучения/понимания?
...
Рейтинг: 0 / 0
29.04.2015, 13:16
    #38948525
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
перечитал тему, ссылку на которую поставил выше про getValueAt(...)
немного не то... там в коде getValueAt() вызывается setValueAt(...), у меня же такого нет...
...
Рейтинг: 0 / 0
29.04.2015, 13:20
    #38948532
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Вставь Thread.dumpStack() и будет видно откуда вызывается. Идея, например подсвечивает рекурсии, если причина в них.
...
Рейтинг: 0 / 0
29.04.2015, 13:26
    #38948546
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Вставил Thread.dumpStack(); сразу за
System.out.println("show user id:" + i++);
Вот копипаст между 3 и 4 счетчиками, так скажем...

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
show user id:3
	at javax.swing.JViewport.paint(JViewport.java:731)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
	at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5239)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1529)
	at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1452)
	at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
	at javax.swing.JComponent.paint(JComponent.java:1041)
	at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
	at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:78)
	at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:115)
	at java.awt.Container.paint(Container.java:1967)
	at java.awt.Window.paint(Window.java:3877)
	at javax.swing.RepaintManager$3.run(RepaintManager.java:819)
	at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
	at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:745)
	at java.awt.EventQueue.access$300(EventQueue.java:103)
	at java.awt.EventQueue$3.run(EventQueue.java:706)
	at java.awt.EventQueue$3.run(EventQueue.java:704)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:715)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
java.lang.Exception: Stack trace
	at java.lang.Thread.dumpStack(Thread.java:1365)
	at nix.tables.models.RequestTableModel.getValueAt(RequestTableModel.java:54)
	at javax.swing.JTable.getValueAt(JTable.java:2717)
	at javax.swing.JTable.prepareRenderer(JTable.java:5719)
	at javax.swing.plaf.synth.SynthTableUI.paintCell(SynthTableUI.java:684)
	at javax.swing.plaf.synth.SynthTableUI.paintCells(SynthTableUI.java:581)
	at javax.swing.plaf.synth.SynthTableUI.paint(SynthTableUI.java:365)
	at javax.swing.plaf.synth.SynthTableUI.update(SynthTableUI.java:276)
	at javax.swing.JComponent.paintComponent(JComponent.java:779)
	at javax.swing.JComponent.paint(JComponent.java:1055)
	at javax.swing.JComponent.paintChildren(JComponent.java:888)
	at javax.swing.JComponent.paint(JComponent.java:1064)
show user id:4
...
Рейтинг: 0 / 0
29.04.2015, 13:29
    #38948552
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Не-не. Так не интересно. getValueAt вызывается для каждой ячейки. Зачем вы этот факт игнорируете?
Интересны вызовы, когда UI уже полностью отрисован и стабилен. А метод почему-то продолжает вызываться.
...
Рейтинг: 0 / 0
29.04.2015, 13:37
    #38948567
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Blazkowicz,

уфф, я кажется нашел проблему, она в была моем TableCellRenderer, сейчас я его подебажу маленько.
Но и так сразу увидел, что getValueAt() в нем вызывается...
Убрал с ячеек его и постоянные вызовы прекратились...
...
Рейтинг: 0 / 0
29.04.2015, 13:51
    #38948591
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
В моем TableCellRenderer()
была строчка:

Код: java
1.
table.setRowHeight(row, 55);



Закомментил её, все стало нормально... хм...
...
Рейтинг: 0 / 0
29.04.2015, 14:02
    #38948616
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Swing бесконечный getConnection() :)
Blazkowicz,

Спасибо огромаднейшее за помощь!
Разобрались, по крайней мере, с одной проблемой, теперь займусь изучением замечаний из второго поста это темы :)
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Swing бесконечный getConnection() :) / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]