Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Кто и где закрашивает старый овал


Автор: Prol 11.1.2008, 13:49
Этот апплет рисует красный овал там, где нажимается мышка.

Но мне непонятно, кто и где закрашивает старый овал в цвет фона?
Я не люблю, когда программы делают то, чего я их не прошу. В тексте апплета есть как рисуется новый овал, но нету как затирается старый овал :о)

Код

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class ClickMe extends Applet implements MouseListener {
    private Spot spot = null;
    private static final int RADIUS = 7;

    public void init() {
     addMouseListener(this);
    }

    public void paint(Graphics g) {
     //draw a black border and a white background
     g.setColor(Color.blue);
     g.fillRect(0, 0, getSize().width - 1, getSize().height - 1);
     g.setColor(Color.black);
     g.drawRect(0, 0, getSize().width - 1, getSize().height - 1);

     //draw the spot
     g.setColor(Color.red);
     if (spot != null) {
         g.fillOval(spot.x - RADIUS, spot.y - RADIUS, RADIUS * 2, RADIUS * 2);
        }
    }

    public void mousePressed(MouseEvent event) {   
     if (spot == null) {
         spot = new Spot(RADIUS);
     }
     spot.x = event.getX();
     spot.y = event.getY();
     repaint();
    }

    public void mouseReleased(MouseEvent event) {}
    public void mouseClicked(MouseEvent event) {}
    public void mouseEntered(MouseEvent event) {}
    public void mouseExited(MouseEvent event) {}
}

public class Spot {
    public int size;
    public int x, y;
  
    public Spot(int intRadius) {
        size = intRadius;
        x = -1;
        y = -1;
    }
}


Автор: Platon 11.1.2008, 14:09
Код

g.fillRect(0, 0, getSize().width - 1, getSize().height - 1);

а это по твоему что?!

Автор: Prol 11.1.2008, 14:15
Цитата(Platon @ 11.1.2008,  14:09)
Код

g.fillRect(0, 0, getSize().width - 1, getSize().height - 1);

а это по твоему что?!

Если это закомментировать, то всё равно старый овал кто-то затирает :о)

Автор: Metal_Heart 11.1.2008, 14:28
Prol,  smile 

Вот ответ на твой вопрос:
Код

 repaint();

Ты же не хранишь ранее нарисованные фигуры? Нет? А кто это должен делать?
Цитата(Prol @  11.1.2008,  13:49 Найти цитируемый пост)
Я не люблю, когда программы делают то, чего я их не прошу.

Вот они и не стали этого реализовывать

Автор: Prol 11.1.2008, 14:33
Цитата(Metal_Heart @ 11.1.2008,  14:28)
Prol,  smile 

Вот ответ на твой вопрос:
Код

 repaint();

Ты же не хранишь ранее нарисованные фигуры? Нет? А кто это должен делать?

Нипанятнаааа...

Как сделать так, чтобы "кто-то" не затирал старый овал, если его об этом не прошу?

Автор: Metal_Heart 11.1.2008, 14:39
Цитата(Prol @  11.1.2008,  14:33 Найти цитируемый пост)
Как сделать так, чтобы "кто-то" не затирал старый овал, если его об этом не прошу?


Prol, ну пойми ты наконец, что пока ты САМ не позаботишься о сохранении своих данный их никто хранит не будет!!!

А чтоб тебе сохранить свои овалы - создаешь промежуточный буффер, типа Image - кажется.
Рисуешь в нем, затем при repaint() выводишь на экран.

У этого метода есть ещё несколько побочных плюсов ...

Автор: batigoal 11.1.2008, 14:46
Prol, при reapint происходит полная перерисовка. Если тебе нужно, чтобы при этом рисовались ещё и старые изображения, тебе придется самому об этом позаботиться.

Автор: Prol 11.1.2008, 14:46
Цитата(Metal_Heart @ 11.1.2008,  14:39)
Prol, ну пойми ты наконец, что пока ты САМ не позаботишься о сохранении своих данный их никто хранит не будет!!!

А чтоб тебе сохранить свои овалы - создаешь промежуточный буффер, типа Image - кажется.
Рисуешь в нем, затем при repaint() выводишь на экран.


Извините, я новик в Java.

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

Кто стирает мой старый овал без спросу?
Как сказать ему, чтобы он не стирал мой старый овал?

Добавлено через 2 минуты и 9 секунд
Цитата(batigoal @ 11.1.2008,  14:46)
Prol, при reapint происходит полная перерисовка. Если тебе нужно, чтобы при этом рисовались ещё и старые изображения, тебе придется самому об этом позаботиться.

Что значит "полная перерисовка"?

Перерисовка чего? Всего окна или только овала?

Извините, я не могу уловить логику Java...

Автор: Metal_Heart 11.1.2008, 14:53
Цитата(Prol @  11.1.2008,  14:46 Найти цитируемый пост)
Перерисовка чего? Всего окна или только овала?

перерисовка того компонента, на ком вызван repaint().

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

Автор: Prol 11.1.2008, 14:56
Цитата(Metal_Heart @ 11.1.2008,  14:53)
Цитата(Prol @  11.1.2008,  14:46 Найти цитируемый пост)
Перерисовка чего? Всего окна или только овала?

перерисовка того компонента, на ком вызван repaint().

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

Я не нашёл исходного кода метода repaint()

 smile 

Автор: batigoal 11.1.2008, 15:03
Цитата(Prol @  11.1.2008,  15:56 Найти цитируемый пост)

Я не нашёл исходного кода метода repaint()

Метод repaint() стирает изображение компонента и вызывает paint(), который выводит новый овал. В твоем коде он не объявлен, и наследуется из класса Applet.

Автор: Prol 11.1.2008, 15:14
Цитата(batigoal @ 11.1.2008,  15:03)
Цитата(Prol @  11.1.2008,  15:56 Найти цитируемый пост)

Я не нашёл исходного кода метода repaint()

Метод repaint() стирает изображение компонента и вызывает paint(), который выводит новый овал. В твоем коде он не объявлен, и наследуется из класса Applet.

Насколько я понимаю, метод repaint() в исходном тексте вызываетcя для объекта g.

Единственное место, где я вижу рисование овала - это метод g.paint()
Он рисует новый овал.

То есть по умолчанию метод g.repaint() затирает любое изображение перерисовкой фона, который фон указан для объекта g ?

Добавлено через 10 минут и 25 секунд
Метод paint() для объекта g мною переопределён, если вы прочитаете исходник.
В моём методе нету затирания старого овала.
Кто затирает старый овал?

Код

public void paint(Graphics g) {
     //draw the spot
     g.setColor(Color.red);
     if (spot != null) {
         g.fillOval(spot.x - RADIUS, spot.y - RADIUS, RADIUS * 2, RADIUS * 2);
        }
    }

Автор: batigoal 11.1.2008, 16:11
Prol, прочитай ещё раз моё сообщение.
Цитата(batigoal @  11.1.2008,  16:03 Найти цитируемый пост)
Метод repaint() стирает изображение компонента и вызывает paint()


Добавлено через 1 минуту и 37 секунд
Цитата(Prol @  11.1.2008,  16:14 Найти цитируемый пост)
метод repaint() в исходном тексте вызываетcя для объекта g.

Для апплета ClickMe, если быть точным. g - это просто графический контекст.

Автор: Prol 11.1.2008, 16:37
Цитата(batigoal @ 11.1.2008,  16:11)
Цитата(Prol @  11.1.2008,  16:14 Найти цитируемый пост)
метод repaint() в исходном тексте вызываетcя для объекта g.

Для апплета ClickMe, если быть точным. g - это просто графический контекст.

g - это объект класса Graphics, как я понимаю из описания.
А repaint() - это метод объекта ClickMe класса Applet.
Я правильно понимаю?

Вопрос остаётся открытым, какой метод какого объекта меняет цвет на том месте, где был нарисован старый овал?

Поскольку метод ClickMe.paint() мною переопределён, то видимо у ClickMe, а точнее у класса Applet, от которого ClickMe унаследован,  есть какой-то невидимый метод, который затирает старый овал?





Автор: batigoal 11.1.2008, 17:21
Prol, повторяю в третий раз - это делает метод repaint().

Автор: dorogoyIV 11.1.2008, 18:18
вот посмотри: - здесь можно таскать инажимать
Код

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class DrawOval extends JFrame
                      implements MouseListener,
                          MouseMotionListener
{
 int x=100, y=100;

 DrawOval()
 {
  setBounds(100,100,400,300);
  addMouseListener(this);
  addMouseMotionListener(this);
 }

 public void paint(Graphics g)
 {
  g.drawOval(x, y, 10, 10);
 }

 public void mouseEntered(MouseEvent e){}
 public void mouseExited(MouseEvent e){}
 public void mousePressed(MouseEvent e){}
 public void mouseReleased(MouseEvent e){}

 public void mouseClicked(MouseEvent e)
 {
  x=e.getX();
  y=e.getY();
  repaint();
 }

 public void mouseMoved(MouseEvent e){}
 public void mouseDragged(MouseEvent e)
 {
  x=e.getX();
  y=e.getY();
  repaint();
 }

 public static void main(String [] args)
 {
  JFrame f=new DrawOval();
  f.setVisible(true);
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
}


Автор: Prol 11.1.2008, 21:20
Цитата(batigoal @ 11.1.2008,  17:21)
Prol, повторяю в третий раз - это делает метод repaint().

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

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

Автор: w1nd 11.1.2008, 23:49
Цитата(Prol @  11.1.2008,  21:20 Найти цитируемый пост)
Повторю в третий раз, как сказать етому репайнту, чтобы он не делал того, что я его не прошу?

Никоим образом.

Цитата(Prol @  11.1.2008,  14:46 Найти цитируемый пост)
По опыту я знаю, что если я нарисовал один пиксел на экране, то он будет нарисованный, пока я сам его оттуда не сотру другим пикселом.

Такое возможно только в однооконных системах. В многооконной системе каждое окно и каждый компонент должны уметь полностью нарисовать себя в любой момент, потому что экран не принадлежит ни одному из них. Если вы нарисовали овал #1 и хотите, чтобы он остался на месте, вы должны перерисовывать его всякий раз, когда вызывается paint().

Цитата(Prol @  11.1.2008,  21:20 Найти цитируемый пост)
Я не привык, чтобы мои программы делали то, чего я в них явно не прописал.

Вы ничего не написали в вашей программе для того, чтобы однажды нарисованные фигуры сохранялись.

Автор: batigoal 12.1.2008, 00:08
Цитата(Prol @  11.1.2008,  22:20 Найти цитируемый пост)
Повторю в третий раз, как сказать етому репайнту, чтобы он не делал того, что я его не прошу?

Раньше у тебя этот вопрос не звучал, было только - "кто?" 
Думаю, ты можешь его переопределить у себя в классе, но это - неправильный подход. Правильный - это запомнить тем или иным образом предыдущие положения овалов и отрисовывать их все в paint().

Автор: Prol 12.1.2008, 01:30
Я понял, в чём проблема. :о)))

Я привык, что монитор (окно) - это память. Например:
- рисуем пиксел в координатах 100,100
- рисуем пиксел в координатах 200,200

Пока мы ничего не рисуем в координатах 100,100, то там останется пиксел, который мы нарисовали раньше. 
Поэтому меня напугало исчезновение овала со старого места.

А вот что я понял:
Что при любом событии перерисовывается полностью всё окно, начиная от фона и заканчивая каждым объектом.

Я привык перемещение объекта программировать так: сначала его стереть на старом месте, потом нарисовать на новом.

А тут в Java получается, что я его на новом месте нарисовал своим методом paint, а кто-то его на старом месте стёр. А я не люблю, чтобы моя прога делала что-то без моего на то прямого указания.

Скачал исходники, нашёл repaint в java.awt.Component и понял, что при любом событии вызывается пайнт контейнера, который полностью его перерисовывает, начиная с фона. Фон перерисовывается. старый овал стирается, потом рисуется новый овал. :о))) 

Зверство. Я не привык чтобы реакцией на любое событие была перерисовка всего окна со всеми объектами изображёнными в окне... 

а потом удивляются, куда делась мощность современных компов...

да просто программисты не мудрствуя лукаво при любом событии заново перерисовывают всё окно... 

нда...

Автор: w1nd 12.1.2008, 01:52
Prol, это не свойство java или ещё какого-либо runtime. Это свойство любой графической оконной системы. Отродясь. Уже лет двадцать как. И именно для того, чтобы ресурсов компьютера (в данном случае - памяти) хоть на что-то хватало. Вылезайте уже из каменного века - текстовых оконных систем smile 

Цитата(Prol @  12.1.2008,  01:30 Найти цитируемый пост)
Я привык, что монитор (окно) - это память. Например:- рисуем пиксел в координатах 100,100- рисуем пиксел в координатах 200,200

Эта память разделяется между всеми компонентами, которые могут перекрываться. Вы что же думаете, что в видеопамять можно запихать эдак сотню-другую видеостраниц?!

Автор: Prol 12.1.2008, 02:11
Да я понял :о)
Раньше компьютеры были большие и памяти имели мало, поэтому приходилось в сто килобайт писать всё приложение причём с картинками, которое в реалтайме обслуживало сотню юзеров :о)
А сейчас компьютеры маленькие, память имеют - экономить не нужно, так что можно и окна перерисовывать полностью, плевать на ресурсы, потому что обслуживает одного юзера  :о)))

В видеопамять можно запихнуть хоть тысячу видеостраниц :о) Прерывание на загрузку отсутствуещей в памяти страницы ещё никто не отменял.

Автор: w1nd 12.1.2008, 02:23
Цитата(Prol @  12.1.2008,  02:11 Найти цитируемый пост)
Раньше компьютеры были большие и памяти имели мало, поэтому приходилось в сто килобайт писать всё приложение причём с картинками, которое в реалтайме обслуживало сотню юзеров :о)А сейчас компьютеры маленькие, память имеют - экономить не нужно, так что можно и окна перерисовывать полностью, плевать на ресурсы, потому что обслуживает одного юзера  :о)))

Вы бы хоть прочитали, что я написал (если сами не понимаете) и немножко подумали прежде.

Цитата(Prol @  12.1.2008,  02:11 Найти цитируемый пост)
В видеопамять можно запихнуть хоть тысячу видеостраниц :о) Прерывание на загрузку отсутствуещей в памяти страницы ещё никто не отменял.

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

Автор: nornad 12.1.2008, 03:47
Цитата(Prol @  12.1.2008,  05:11 Найти цитируемый пост)
В видеопамять можно запихнуть хоть тысячу видеостраниц

Если я ничего не путаю, то в винде, например, сейчас доступна либо одна страница памяти, либо есть возможность получить доступ ко второй странице и использовать её в качестве видеобуфера. Нарисовал в буфер - перключился на него, нарисовал в предыдущем - перключился. Но это - нативная штука и в Java вроде бы явным образом не присутствует (хотя гарантировать не буду, ибо на этом уровне не лазал).
Про линукс и другие платформы тоже ничего не скажу, ибо не знаю.

P.S. Писать на Java используя парадигмы DOS'а - это круто. smile Скоро начнём на Java обрабатывать прерывания клавиатуры и дисков.

Автор: Prol 12.1.2008, 04:06
Цитата(nornad @ 12.1.2008,  03:47)
P.S. Писать на Java используя парадигмы DOS'а - это круто. smile Скоро начнём на Java обрабатывать прерывания клавиатуры и дисков.

 smile 

На Java работают микроволновки и стиральные машинки, и прекрасно обрабатывают прерывания от электромоторов и кнопок на панелях управления этими дивайсами :о)

P.S. Рекомендую почитать, что было до "парадигмы ДОСа" :о) Вы удивитесь, насколько опошлились программисты, развращённые безответственностью за свои программы. Более того, программисты воинственно обнаглели, объявив всему миру в своих так называемых "лицензиях", что не несут ответственности за последствия действия своих программ.

Автор: nornad 12.1.2008, 06:00
Цитата(Prol @  12.1.2008,  07:06 Найти цитируемый пост)
На Java работают микроволновки и стиральные машинки, и прекрасно обрабатывают прерывания от электромоторов и кнопок на панелях управления этими дивайсами :о)

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

Чтобы писать сносно на каком-либо языке надо в общих чертах с ним разобраться и знать основные фразы. Чтобы писать правильно - надо понять язык и принять его. Заметь, "сносно" никогда не бывает лучшего качества, чем "правильно".

Цитата(Prol @  12.1.2008,  07:06 Найти цитируемый пост)
Рекомендую почитать, что было до "парадигмы ДОСа" :о) Вы удивитесь

Будем пиписькамивозрастом меряться? Я в курсе, что было "до". Я знаю, как "надо". Но в современных условиях частью критериев можно немного пренебречь. Отсюда и GC, кстати. Потому что памяти сейчас много. А когда совсем не хватает - вот тогда наступают тяжёлые времена для развращённой прыщавой восторженной молодёжи smile  и всех приходится выручать кому-то из старичков smile  (ну, иногда вместо старичка на помощь приходит сетевой совет из далёкого прошлого нашей планеты или коллективный разум нескольких форумов).
Но при всём при этом эти прыщавые юнцы, приняв современную идеологию, будут писать быстрее тебя с незыблемыми принципами. И могут оттяпать немалый кусок хлеба, если не подсуетиться вовремя.  smile 

P.S. Если кому интересно, мой возраст есть в профиле. Точнее, дата рождения. Не старик, конечно, но и не прыщав уже, как мне кажется.  smile 

Автор: Prol 12.1.2008, 07:32
Цитата(nornad @ 12.1.2008,  06:00)
Но при всём при этом эти прыщавые юнцы, приняв современную идеологию, будут писать быстрее тебя с незыблемыми принципами. И могут оттяпать немалый кусок хлеба, если не подсуетиться вовремя.  smile 

Ну и пусть тяпают :о) Всех денег не заработаешь :о) Тем более, скоро пенсия :о) Пусть молодые суетятся, пока ихние девки моложе :о)

Автор: nornad 12.1.2008, 08:17
Цитата(Prol @  12.1.2008,  10:32 Найти цитируемый пост)
Тем более, скоро пенсия

Ладно, уел, крыть нечем.  smile 

Автор: Prol 12.1.2008, 08:20
Цитата(nornad @ 12.1.2008,  08:17)
Ладно, уел, крыть нечем.  smile

 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)