Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зависание GUI 
:(
    Опции темы
shutffl
Дата 29.6.2011, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008

Репутация: нет
Всего: 3



Доброго времени суток!!

Жизнь заставила после 10 лет отбрыкивания от Java таки сесть за её изучение. И сразу же решил написать проект по работе дабы в боевых действиях познать прелести языка. Суть проблемы сводится к подвисанию GUI. Сразу привожу код.

mWindow.java:
Код

package su.shadowmoon.testcv;



import java.awt.BorderLayout;

import java.awt.EventQueue;



import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.border.EmptyBorder;

import java.awt.GridLayout;

import javax.swing.JButton;

import su.shadowmoon.canvas.Canvas;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;



public class mWindow extends JFrame {



    private JPanel contentPane;



    /**

     * Launch the application.

     */

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {

            public void run() {

                try {

                    mWindow frame = new mWindow();

                    frame.setVisible(true);

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        });

    }



    /**

     * Create the frame.

     */

    public mWindow() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setBounds(100, 100, 450, 300);

        contentPane = new JPanel();

        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

        setContentPane(contentPane);

        contentPane.setLayout(new GridLayout(1, 0, 0, 0));

        

        Canvas panel = new Canvas();

        contentPane.add(panel);

        

        final JButton button = new JButton("0");

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {

                button.setText("" + (Integer.parseInt(button.getText()) + 1));

            }

        });

        contentPane.add(button);

    }



}


Canvas.java:
Код

package su.shadowmoon.canvas;



import java.awt.*;

import java.util.Random;



import javax.swing.*;



public class Canvas extends JPanel {

    

    public void Canvas () {

        

        setSize(300, 300);

        repaint();

        

    }

    

    public void paintComponent(Graphics g) {

        super.paintComponent(g);        

        Graphics2D g2 = (Graphics2D) g;

        

        g2.drawRect(0, 0, 300, 300);

        

        for (int i=0; i<1000000; i++) {

            g2.drawLine(

                    (int)Math.round(-300 + 600*Math.random()),

                    (int)Math.round(-300 + 600*Math.random()),

                    (int)Math.round(-300 + 600*Math.random()),

                    (int)Math.round(-300 + 600*Math.random())

                    );

        }

    }

    

}



Прошу сильно не бить, ибо язык почти не знаю - могут быть серьезные огрехи, но логика есть логика. В данном примере, как это видно из кода, JPanel рисует 1000000 количество линий в области 300*300 пикселей. Это сделано для задержки.

Как сделать, чтобы GUI реагировал во время рисования линий? То есть, чтобы работала нажатие на кнопку, считающую количество нажатий на ней. Это элементарный кусок кода, переписаный аналогчно (по принципу работы GUI) реальному приложению, которое должно обрабатывать в реальном времени изображение с камеры и делать фотки по нажатию на кнопку. Но и там, и там GUI просто висит. Знаю, что ответ где-то рядом. Подозреваю, что копать надо в сторону "Is Java threadsafely?". Но с потоками на Java пока туго, ибо куда их тут впихнуть - я хз.

Заранее спасибо.
--------------------
shadowmoon
PM MAIL   Вверх
jk1
Дата 29.6.2011, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 21
Всего: 75



Цитата

Как сделать, чтобы GUI реагировал во время рисования линий?


Рисовать линии в отдельном потоке на off-screen изображении и затем выводить на экран. Хотите видеть промежуточные результаты  - отрисовывайте полуготовое изображение.

Цитата

Is Java threadsafely?


Про сам язык так говорить не слишком корректно. А вот про Swing, который Вы используете, можно сказать однозначно - небезопасен. Смотрите в сторону класса SwingWorker, который как раз предназначен для выноса тяжелых задач из EDT (основной поток Swing'а).
Публикацию промежуточных результатов SwingWorker также поддерживает. 

Читать тут


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
shutffl
Дата 30.6.2011, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008

Репутация: нет
Всего: 3



Спасибо, почитаю.
--------------------
shadowmoon
PM MAIL   Вверх
shutffl
Дата 30.6.2011, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008

Репутация: нет
Всего: 3



Хорошо, а если вместо заглушки вставить код на вывод потокового видео или аудио? Например, используя JavaCV или VLC Java binding? 
--------------------
shadowmoon
PM MAIL   Вверх
jk1
Дата 30.6.2011, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 21
Всего: 75



Цитирую документацию
Цитата

JavaCV also comes with hardware accelerated full-screen image display (CanvasFrame),


так что здесь все уже cделано за Вас, этот компонент сам будет все отрисовывать.


Это сообщение отредактировал(а) jk1 - 30.6.2011, 16:43


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
aleksandy
Дата 1.7.2011, 07:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 260
Регистрация: 17.12.2006

Репутация: 1
Всего: 5



Думаю не лишним будет ознакомиться вот с этим: устройство, синхронизация.

PM   Вверх
shutffl
Дата 1.7.2011, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008

Репутация: нет
Всего: 3



Спасибо, сейчас приступаю к ознакомлению. До этого писал нечто подобно на связке Qt + libvlc, но там был другой проект - радио. На Gtk+ так и не получилось адекватно реализовать потоки, чтобы GUI не подвисал. А тут решил под Android ПО пописать системное, а офф язык раработки только Java (C/C++ и python слишком коряво реализованы плюс в GUI все равно JavaScript-функция "биндится" для стороннего кода).
--------------------
shadowmoon
PM MAIL   Вверх
shutffl
Дата 1.7.2011, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008

Репутация: нет
Всего: 3



Цитата(jk1 @  30.6.2011,  12:35 Найти цитируемый пост)
так что здесь все уже cделано за Вас, этот компонент сам будет все отрисовывать.

Да, но от требует NamedWindow, что для моих целей не годится. Грубо говоря, мне надо, чтобы было две компоненты 300*300 (реально 320*240) в горизонтальном layout, где в одном идет потоковое изображение с камеры, а во второй попадает изображение (фото) по нажатию кнопки. После этого фото можно сохранить.

--------------------
shadowmoon
PM MAIL   Вверх
jk1
Дата 1.7.2011, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 21
Всего: 75



Цитата

Да, но от требует NamedWindow, что для моих целей не годится. Грубо говоря, мне надо, чтобы было две компоненты 300*300 (реально 320*240) в горизонтальном layout, где в одном идет потоковое изображение с камеры, а во второй попадает изображение (фото) по нажатию кнопки. После этого фото можно сохранить.

Не прошло и недели, а мы уже выяснили в чем же состоит задача.  smile 

А если серьезно, то вот что я могу Вам предложить. Запускаете отдельный SwingWorker, который читает с камеры и получает BufferedImage.
Код

IplImage img = grabber.grab();
...
BufferedImage image = img.getBUfferedImage();

Прочитанные изображения публикуются как промежуточный результат (возможно пачками). Реализация метода process() в вашем SwingWorker() передает изображение панели и вызывает её принудительную перерисовку.

А дальше надо будет смотреть, что выйдет. Если будут задержки и тормоза возможно придется прикрутить промежутчный буфер для изображений, а панель перерисовывать по таймеру. 


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
shutffl
Дата 1.7.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008

Репутация: нет
Всего: 3



Спасибо. Про BufferedImage уже знал, так как само изображение получаю. Проблема была в том, что поток буфферизируется и изображения по клику мышки получаются не текущие (которых даже не видно), а следующие в потоке.
--------------------
shadowmoon
PM MAIL   Вверх
shutffl
Дата 1.7.2011, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 18.8.2008

Репутация: нет
Всего: 3



На C++ (с GUI на Qt) уже все написал. Но хочу на Java.
--------------------
shadowmoon
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0596 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.