Форум программистов, компьютерный форум, киберфорум
Java: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
2 / 2 / 0
Регистрация: 05.03.2013
Сообщений: 49

Стирается рисунок

28.03.2013, 09:33. Показов 4217. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Помогите разобраться как правильно рисовать на панели чтоб рисунок не стирался открывающимися диалоговыми окнами.
Сейчас делаю так:

Java
1
2
3
4
Graphics2D g2d;  
g2d = (Graphics2D) jPanel1.getGraphics();
g2d.setColor(Color.red);
g2d.drawRect(100,100,100,100);
Всё рисуется нормально. Но любое окно вызванное поверх этой панели в программе, или даже не в программе а окно другой программы стирает этот рисунок !

Добавлено через 21 минуту
Да и ещё забыл сказать.
Прорисовка делается по событию
Java
1
jPanel1AncestorResized
Так вот что происходит:
Запускаем программу, окно прорисовывается, всё норм.
Открываем любое окно - рисунок на панели пропадает.

Разворачиваем окно на весь экран и затем опять сворачиваем его.
После этой нехитрой операции всё работает нормально.
На развёрнутом окне - окна других программм стирают рисунки.

Прям загадка какая то
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.03.2013, 09:33
Ответы с готовыми решениями:

Стирается изображение в jPanel
Добрый вечер. Уже долгое время не получается оставить изображение на jPanel после его свертывания или перекрытия его другими окнами....

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

Графический Рисунок(нужно составить рисунок на С++ в форме желтой звезды)
нужно составить рисунок на С++ в форме желтой звезды

11
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
28.03.2013, 11:13
делайте отрисовку в paintComponent, а не в paint
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
28.03.2013, 11:30
Цитата Сообщение от mutagen Посмотреть сообщение
делайте отрисовку в paintComponent, а не в paint
Да там даже не в paint делается, а по событию, т.е. вне цикла отрисовки.
0
2 / 2 / 0
Регистрация: 05.03.2013
Сообщений: 49
28.03.2013, 13:25  [ТС]
Полностью выглядит так:

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
........
........
........
........
 
        ActionListener taskTimerResize = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                actionTimerResize();
            }
        };
        timerResize = new Timer(400, taskTimerResize);
        timerResize.setRepeats(false);
........
........
........
........
 
    private void actionTimerResize() {
        myDraw();
    }
 
    private void jPanel1AncestorResized(java.awt.event.HierarchyEvent evt) {                                             
        if (timerResize.isRunning()) {
            timerResize.restart();
        } else {
            timerResize.start();
        }
    }       
 
     private void myDraw() [
        Graphics2D g2d;  
        g2d = (Graphics2D) jPanel1.getGraphics();
        g2d.setColor(Color.red);
        g2d.drawRect(100,100,100,100);
     ]
Добавлено через 1 час 32 минуты
Проверил.
Создал новый класс прямо по примеру, назвал его MyjPanel1
Воткнул его вместо панели jPanel1:

Java
1
2
    jPanel1 = new MyjPanel1();
    jPanelService.add(jPanel1);
Да, панель прорисовывается мордочкой из примера, и она действительно никуда не девается.
Но дальше то как? Всё что ни ресую дальше хоть в этом классе хоть в вызывающем - всё стирается.
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
28.03.2013, 13:30
Цитата Сообщение от konrads Посмотреть сообщение
Да, панель прорисовывается мордочкой из примера, и она действительно никуда не девается.
Но дальше то как? Всё что ни ресую дальше хоть в этом классе хоть в вызывающем - всё стирается.
Почитайте статью целиком, там объясняется, почему так и должно быть, и что с этим делать.
0
2 / 2 / 0
Регистрация: 05.03.2013
Сообщений: 49
28.03.2013, 17:18  [ТС]
ошибочка вкралась

Java
1
2
    MyjPanel1 jPanel1 = new MyjPanel1();
    jPanelService.add(jPanel1);
Добавлено через 3 часа 38 минут
Понятно, попробую разобраться если мозгов хватит
0
2 / 2 / 0
Регистрация: 05.03.2013
Сообщений: 49
01.04.2013, 09:29  [ТС]
Ну в принципе разобрался.
Но этот способ для того, что я задумал как то не очень подходит. Суть в том, что мне нужно на панели, в зависимости от разных многих событий рисовать разные многие детали с обращением к базе данных и т.д., а не только от изменения размеров, где перерисовывается всё уже отрисованное в новом масштабе, и если всё это делать так как предложено, то ойёёй как повыпендриваться надо.

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

на форме три панели, север - jPaneTablo, центр - myDrawPane, юг - jPaneService.
На панелях jPaneTablo и jPaneService - различные стандартные компоненты, кнопки, текстовые поля и т.д.

Центр перерисовываю сам при изменении размера, и в зависимости от событий рисую там всякое разное. Рисую именно на панели (Getgraphics)

для того чтоб отключить автопрорисовку на форме, переопредилил функцию paint формы, и сделал её просто пустой :
Java
1
2
3
    @Override
    public void paint(Graphics g) {
    }
на событие изменения размера (оно у меня происходит по таймеру) делаю прорисовку всех панелей так:
Java
1
2
3
4
5
    private void actionTimerResize() {
        myDrawPane();
        jPaneTablo.repaint();
        jPaneService.repaint();
    }
Ну так вот, под виндами всё работает как надо.
Вопрос: Можно ли так делать, насколько это корректно и не вылезут ли со временем камешки из под земли ?

Добавлено через 20 минут
Поправлю, ошибочка небольшая
Java
1
2
3
4
5
  private void actionTimerResize() {
        myDraw();  // прорисовка графической панели в центе формы
        jPaneTablo.repaint();
        jPaneService.repaint();
    }
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
03.04.2013, 18:21
Плохо. Отключать прорисовку формы нельзя. По таймеру - неудачное решение. Если таймер редкий - будут задержки, если частый - бессмысленная нагрузка. Перерисовка должна быть исключительно когда надо, т.е. по событию.

Я вообще не понимаю, зачем надо было отключать перерисовку формы.
0
2 / 2 / 0
Регистрация: 05.03.2013
Сообщений: 49
03.04.2013, 18:57  [ТС]
Перерисовку формы я решил отключить чтоб форма самостоятельно не реагировала на появление всяких окон над ней, и не стирала рисунки намалёваные мною. По факту получилось что ничего не стирается.

Чтоб решить вопрос с перерисовкой панелей во время изменения размеров, я поступил так :
отслеживаю событие myDravPaneAncestorResized

Так как при ручном изменении размера формы это событие происходит слишком часто, а моя перерисовка относительно медленная, я перерисовку делаю по однократному таймеру, который перезапускается по этому событию.
Приблизительно так:
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
..........
..........
        ActionListener taskTimerResize = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                actionTimerResize();
            }
        };
        timerResize = new Timer(400, taskTimerResize);
        timerResize.setRepeats(false);
..........
..........
 
    private void actionTimerResize() {
        myDraw();
        jPaneTablo.repaint();
        jPaneService.repaint();
    }
 
    private void myDravPaneAncestorResized(java.awt.event.HierarchyEvent evt) {                                             
        if (timerResize.isRunning()) {
            timerResize.restart();
        } else {
            timerResize.start();
        }
    }
Т.Е. полная отрисовка происходит при изменении размеров однократно с небольшой задержкой
Кроме полной перерисовки есть куча функций рисования маленьких фрагментов.

Сама перерисовка myDraw - Сложная функция, которая считывает базу данных, и в зависимости от значений перерисовывает много разных деталей (используя нужные для этого функции). А в постоянном режиме, в зависимости от действий пользователя, эти всякие мелкие детали отрисовываются на панели, и фиксируются в базе этими многими функциями (фиксация в базе и для перерисовки во время изменения размера, и для сохранения состояния сложного обьекта)

Ну как то так, сумбурно
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
05.04.2013, 13:41
Цитата Сообщение от konrads Посмотреть сообщение
Перерисовку формы я решил отключить чтоб форма самостоятельно не реагировала на появление всяких окон над ней, и не стирала рисунки намалёваные мною. По факту получилось что ничего не стирается.
Это означает, что Вы так и не поняли, как происходит перерисовка в Java. Образно говоря - Вы построили стол на двух ногах, который падает. Чтобы не падал, вы построили механизм, который непрерывно подпинывает этот стол в направлении, обратном падению. А надо было всего лишь третью ногу добавить в нужном месте. В Вашем случае такой третьей ногой будет буферизация. BufferedImage, который содержит то, что Вам надо отрисовать, и БЫСТРО отрисовывается каждый раз, когда этого хочет Java. А сам BufferedImage Вы меняете ровно тогда, когда надо, в зависимости от действий пользователя. Т.е. вместо того, чтобы рисовать прямо на панели, рисуете на буфере. И вся разница. Примеры этого в статье тоже есть.
2
2 / 2 / 0
Регистрация: 05.03.2013
Сообщений: 49
07.04.2013, 09:06  [ТС]
Вы конечно правы по большому счёту, и надо делать всё по правилам. Но в принципе часто ли мы делаем изменение размера? Ну во время запуска, ну развернули разок, ну свернули. Основная идея которую я преследовал - это рисование на панели, и чтоб Java в этот процесс просто не вмешивалась, и не делала перерисовки когда её не просят. В принципе это работает, ну по крайней мере в том виде как я описал, без дальнейших наворотов. По скорости опять же - или я отрисовал 20на20 пикселов квадратик и забыл про это, или через буффер и перерисрвка.
В любом случае спасибо за помощь, до конца я пока не определился, отсутствие опыта на Java конечно меня сильно путает.
0
2 / 2 / 0
Регистрация: 05.03.2013
Сообщений: 49
22.04.2013, 10:31  [ТС]
Вернулся к этому вопросу, действительно ранее предложенный мной способ работает как попало!
Решил проблему следующим образом:
Основной метод перерисовки всей панели поместил как и рекомендовано.
Причём myDrawAfterResize - та же процедурка что и была, только теперь я ей подсовываю другой объект внутри этого класса

А для того чтобы быстро отрисовывать детали без использования буферов и прочего делаю приблизительно так как и раньше, инициализирую статическую переменную типа Graphics2D по таймеру после изменения размера, и рисую прямо там, да и изменение размера - крайне редкий процесс!

В катце, без лишней воды приблизительно так:

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
............
.
.
   public static class MyJPanel extends JPanel {
        
        public MyJPanel() {
            setOpaque(true);
        }
 
        @Override
            public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D)g;
            myDrawAfterResize(g2d);
        }
    }
 
    public static MyJPanel myJPanel = new MyJPanel();
    public static Timer timerResize;
    public static Graphics2D g2dPanel;
............
.
.
............
        ActionListener taskTimerResize = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                actionTimerResize();
            }
        };
        timerResize = new Timer(200, taskTimerResize);
        timerResize.setRepeats(false);
............
.
.
............
    private void actionTimerResize() {
        g2dPanel = (Graphics2D) myJPanel.getGraphics();
    }
...........
.
.
...........
    private void myJPanelAncestorResized(java.awt.event.HierarchyEvent evt) {                                            
        timerResize.restart();
    }
Далее оперативные прорисовки деталей делаем в g2dPanel, а перерисовки делаются автоматом.
Ну и конечно для этого убрал замену метода Paint основной формы.
Помоему теперь получилось неплохо, или я ещё чего то не понимаю.
По крайней мере исчезли все проблемы с видимым на экране рисунком независимо от того что вокруг происходит, рсуется всё быстро и перерисовывается нормально при изменении размеров и при закрытии рисунка другими окнами.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.04.2013, 10:31
Помогаю со студенческими работами здесь

Как создать рисунок и сохранить его в bmp (точечный рисунок)
Здравствуйте, пишу свой графический редактор и вот не знаю как из того что я рисую в графе сконструировать рисунок , а потом сохранить его...

Установите в документе рисунок с кнопкой При нажатии кнопки рисунок должен смениться
Ув. пользователи! Прошу помочь мне с некоторыми задачами по Java Script: 1) Установите в документе рисунок с кнопкой. При нажатии...

На странице есть рисунок. При наведении мыши на этот рисунок он должен измениться
На странице есть рисунок. При наведении мыши на этот рисунок он должен измениться. Когда Вы отведете мышку в сторону, рисунок должен...

Как на фоновый рисунок наложить второй рисунок
Как на рисунок (фон) наложить текст с таблицей? Сама таблица есть не в текстовом формате (в Word), а в виде скриншота, т.е. картинка.

На листе находится рисунок; можно ли сохранить этот рисунок из книги, как отдельный bmp или jpg файл?
1. На листе находится рисунок. Можно ли, сохранить этот рисунок из книги как отделений Bmp или jpg файл. И еще один вопрос: Можно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru