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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> robot в не EDT потоке, Scrinshort не из основного потока 
V
    Опции темы
Mirkes
Дата 5.9.2012, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 2
Всего: 17



Из модального диалога запускается поток, который производит следующую процедуру:
1. По некоему алгоритму нечто отрисовывает в окне основной программы
2. Пытается снять получившуюся картинку с помощью робота.

В результате я получаю вместо кратинок пустые файлы, исключений не возникает. 
Система Windows7

вот фрагмент кода

Код

                        pane.setCSteps(i); \\ Команда отрисовать. Исполнитель упаковывает ее как положено (Следующий фрагмент кода)
                        try {
                            Robot r = new Robot();
                            BufferedImage buf = r.createScreenCapture(new Rectangle(sour.getLocationOnScreen(), sour.getSize()));
                            ImageIO.write(buf, ext, new File(fileName+"-"+cc+ext));
                        } catch (IOException f) {
                            System.out.println(f.getMessage());
                        } catch (AWTException e) {
                            System.out.println(e.getMessage());
                        }



Вот код команды на отрисовку

Код

    public void setCSteps(int step) {
        cSteps = step;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                ready = true;
                drawState();   \\ собственно рисующая программа
                ready = false;
            }
        });
    }


Я не понимаю что происходит. Сообщений об исключениях нет. Рисование вроде происходит, но слишком быстро. А файлы на выходе пустые. 
Подскажите куда смотреть?


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


Эксперт
***


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

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



А где гарантия что на момент снятия скриншота все уже отрисовалось? Из кода этого не видно


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


Опытный
**


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

Репутация: 2
Всего: 17



Гарантии пока нет. Но там что-то точно было, а файлов нет совсем. Пусть будет пока не то, что мне нужно, но ведь нет совсем ничего. Вот что меня напрягает.


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


Эксперт
***


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

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



Результат и правда странный.
Я бы попробовал зашедулить вызов робота также на EDT, причем использовать в обоих случаях не invokeLater, а invokeAndWait.
Так вызов будет синхронным.


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


Опытный
**


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

Репутация: 2
Всего: 17



С отсутствием файла разобрался - не правильно передавал расширение.
Однако проблема состоит даже не в отрисовке, а в принципиальной возможности применения робота.
Существует три сущности.
1. Основное окно программы, в котором что-то рисуется.
2. Модальный диалог, который запускает поток отрисовки и снятия изображений.
3. Собственно тот поток, который передает команду главной форме отрисоваться, а потом вызывает робота для снятия изображения.

Допустим поток (3) может поймать момент завершения отрисовки. При запуске робота в файл выгружается изображение модального диалога, перекрывающее нужный компонент. 

Как снять с компонента изображение так, чтобы было не важно, закрыт он какими-нибудь диалогами, другими программами и т.д.?

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

В Delphi каждый компонент имеет TCanvas, с которого всегда можно считать изображение, даже если компонент не виден на экране. Неужели в Java нет ничего подобного?

Нашел набросок тут. Пока не проверил.


--------------------
Mirkes
PM MAIL   Вверх
Mirkes
Дата 7.9.2012, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 2
Всего: 17



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

       SwingUtilities.invokeAndWait(new Runnable() {  // Необходимо, если задача отрисовки и считывания запускается не из потока
               public void run() {                                        // EDT. Я запускал не из него
                     pane.setCStepSimpl(currStep);                 // некое конфигурирование компонента для отрисовки
                      // Создем BufferedImage нужных размеров и типа. deskTop - тот компонент, изображение которого я хотел считать
                      bI = new BufferedImage(deskTop.getWidth(), deskTop.getHeight(), BufferedImage.TYPE_INT_ARGB);
                      Graphics2D g2 = bI.createGraphics();       // вспомогательное необходимое действо
                       deskTop.paint(g2);                                  // А вот это и есть главное - отрисовка компонента в буфере!
                }
       });
       //Write result
       ImageIO.write(bI, "png", new File(fileName)); // теперь делаем с Image то что хотим. Я записал на диск



Если при возникновении необходимости скопировать изображение компонента возникла в потоке EDT то код получается проще. Пусть
нужный компонент называется deskTop (класс не важен, лишь бы это был потомок компонента), и все что нужно скопировать на нем уже нарисовано. Тогда достаточно следующего кода

Код

       // Создем BufferedImage нужных размеров и типа. deskTop - тот компонент, изображение которого я хотел считать
       BufferedImage bI = new BufferedImage(deskTop.getWidth(), deskTop.getHeight(), BufferedImage.TYPE_INT_ARGB);
       Graphics2D g2 = bI.createGraphics();       // вспомогательное необходимое действо
       deskTop.paint(g2);                                  // А вот это и есть главное - отрисовка компонента в буфере!
       ImageIO.write(bI, "png", new File(fileName)); // теперь делаем с Image то что хотим. Я записал на диск

Детальное описание работы с рисованием на компонентах приведено тут
Возможно стоит написать статью в FAQ, но он временно не работает.
jk1, а где сейчас складывают такие вещи? А то подобных вопросов я встречал на форуме множество, и решение всегда предлагалось через робота. Хотелось бы закрыть тему (не эту, а получения изображения с компонента).

Это сообщение отредактировал(а) Mirkes - 7.9.2012, 08:17


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


Эксперт
***


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

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



Цитата

jk1, а где сейчас складывают такие вещи? 


Раньше было http://base.vingrad.ru/ , но похоже оно умерло. Так что получается, что некуда.


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


Опытный
**


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

Репутация: 2
Всего: 17



При чтении старых цепочек обнаружил ссылку на старый faq, которая сработала!
Может пока новый FAQ мертв, перейти в старый?


--------------------
Mirkes
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.0732 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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