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


Автор: dre 28.7.2006, 18:36
Значит задача такая: есть большая панель с заполненым Графиксом, надо из этой панели вырезать скажем где-то в середине прямоугольник и присвоить его другой панели размером как раз с этот прямоугольник. Причем чтобы на маленькой панели прямоугольник должен расположиться с координаты (0,0). Буду рад любому совету. 

Автор: corewithin 28.7.2006, 18:56
Наследуешь маленькую панель от большой и в методе переопределенном методе paint(Graphics g) вызываешь клипание Графикса 
Код

(
     * @see         java.awt.Graphics#clipRect
     * @see         java.awt.Graphics#setClip(int, int, int, int)
     * @see         java.awt.Graphics#setClip(Shape)
)
 

Автор: dre 28.7.2006, 19:48
Не получается так. Значит в переопределенном методе 
Код

paint(Graphics g) {
super.paint(g);
g.setClip(0,500, 100,100);
}

а на панельке все равно появляется содержание большой с самого начала т.е. с (0,0)  и все что вместилось дальше
причем на размеры клипа плевать все хотели 
а мне надо чтобы отобразился участок только с (0,500) и переместился на начало координат.

Добавлено @ 20:02 
в принципе если поменять местами команды, то он будет отображать только этот участок, но в той же координате, а надо его еще переместить в начало координат, как? 

Автор: powerOn 28.7.2006, 23:29
По данному вопросу у меня имеется предложение след. характера: Определите в классе JPanel вот такой метод:

Код

public BufferedImage getClipImage(int x, int y, int w, int h) {
        BufferedImage buf = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
        super.paint(buf.getGraphics());
        return buf.getSubimage(x, y, w, h);
    }


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

Автор: dre 29.7.2006, 14:12
 В принципе такой способ работает, только надо вызывать не super.paint(g); a this.paint(g);
Но какой-то не красивый способ, через картинки очень ресурсоемко и не понаучному smile А что если у меня очень большая панель и мне ее надо поделить на 20 кусочков это мне надо 20 раз ее перерисовывать, а так не пойдет. неужели в самом классе Графикс не предусмотрены методы для такой задачи?
  

Автор: powerOn 29.7.2006, 17:09
Цитата(dre @  29.7.2006,  15:12 Найти цитируемый пост)
В принципе такой способ работает, только надо вызывать не super.paint(g); a this.paint(g);

всецело согласен.


Цитата(dre @  29.7.2006,  15:12 Найти цитируемый пост)
А что если у меня очень большая панель и мне ее надо поделить на 20 кусочков это мне надо 20 раз ее перерисовывать, 

нет, перерисовываете всю панель в буфер, а потом выделяете getSubimage() двадцать необходимых регионов. И как я понимаю, getSubimage()   не копирует данные и не создает новый рисунок, а возврашает ссылку на регион оригинального рисунка ввиде BufferedImage.
  

Автор: dre 29.7.2006, 17:22
В принципе я так уже и сделал, но теперь есть другая проблема, дело в том что когда я создаю BufferedImage объект то надо задать размеры начальные, а их я в этот момент не знаю, в частности высоту, т.к. чтобы их узнать мне надо вызвать paint панели там они и определяются. Способ задать картинку заведомо большого размера не пойдет, можно ли как-то вызвать этот paint заранее для какого-либо графикса но не задавая ему размеров и не отображая на экране.  

Автор: powerOn 29.7.2006, 17:38
Цитата(dre @  29.7.2006,  18:22 Найти цитируемый пост)
можно ли как-то вызвать этот paint заранее для какого-либо графикса но не задавая ему размеров и не отображая на экране. 


боюсь что нет. Может добавить дополнительный метод для расчета панели? Или агрегировать в панель BufferedImage и прорисовывать в него всю панеть когда необходимо, а потом возвращать её внешним объектам.. так можно будет из метода paint() в буфер положить катринку когда её размеры станут известы... 

Автор: dre 30.7.2006, 12:30
Как тяжело исправлять свои ошибки а предусмотреть их еще трудней smile Дело в том, что если так делать, то это надо перелапачивать половину кода, а это немаленькое количество, да и сроки меня уже поджимают, так что надо выкручиваться исходя из того, что уже имеем...
беда...

Цитата

 агрегировать в панель BufferedImage и прорисовывать в него всю панеть когда необходимо, а потом возвращать её внешним объектам.. 


Мне сначала нада получить весь нарисованный обект будь то графикс или буфер, а потом с ним делать, что захочу в частности резать и вставлять. На даныый момент сначала в paint рисуется вся панель потом, по совету добрых людей, переносится на картинку и из нее режется и вставляется. Сейчас картинка задается заведомо большого размера чтобы все поместилось, но всегда ведь найдется что-то больше чем надо... поэтому надо узнать как-то перед переносом на картинку размер нарисованного,  а это можно сделать лишь вызвав paint панели, значит надо как-то его вызвать раньше... а как...  

З.Ы. объяснил как смог, если не запутал, то это уже успех!    

Автор: powerOn 30.7.2006, 13:09
Цитата(dre @  30.7.2006,  13:30 Найти цитируемый пост)
значит надо как-то его вызвать раньше... а как...  


Вообще говоря размер буфера (BufferedImage) можно установить как размер панели на котором происходит прорисовка. 

Цитата(dre @  29.7.2006,  18:22 Найти цитируемый пост)
когда я создаю BufferedImage объект то надо задать размеры начальные, а их я в этот момент не знаю, в частности высоту, т.к. чтобы их узнать мне надо вызвать paint панели там они и определяются.


а вот это кстати почему? Метод paint получает неизменяемый по размерам Graphics (его размеры совпадают с размерами панели)... как Вы эти размеры определяете? 
Хотелось бы код посмотреть...
 

Автор: dre 30.7.2006, 13:25
То есть я так понял, что если я буду рисовать на графиксе в координате большей чем ее размеры то произойдет исключение что ли? 
 

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

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

Автор: powerOn 30.7.2006, 13:49
Цитата(dre @  30.7.2006,  14:25 Найти цитируемый пост)
То есть я так понял, что если я буду рисовать на графиксе в координате большей чем ее размеры то произойдет исключение что ли? 

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

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

Автор: dre 30.7.2006, 14:07
Цитата

необходимо написать метод определяющий необходимые размеры буфера


Это получается, что сначала надо пройти всю процедуру посчета количества строк, потом установить размеры буфера, а потом заново пройти эту процедуру, но уже с отображением в буфер. А еще проблема в том что на поле шириной в 500 количество строк будет одно, а при ширине в 100 совсем другое, гораздо большее. То есть процедуры  разбиения строчек и рисования на панель либо в буфер (мне в принципе без разницы куда) и доставания этих строчек неразделимы. 

Цитата

просто на экране отобразится только то, что попало в реальные размеры

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

Цитата

Метод paint получает неизменяемый по размерам Graphics (его размеры совпадают с размерами панели)... как Вы эти размеры определяете? 


мне все равно какого размера панель, главное установить потом размеры картинки нужные. т.е просто надо вызвать  paint панели чтобы узнать размер, а потом еще раз этот paint только уже paint(buf.getGraphics())  
А как заставить вызваться paint в первый раз? я пока не додумался... 

Автор: powerOn 30.7.2006, 14:53
Цитата(dre @  30.7.2006,  15:07 Найти цитируемый пост)
т.е. в графиксе содержание все таки будет,

нет, не будет. Лишнее просто не прорисуется и все.

Добавлено @ 15:06 
И потом, Graghics это абстрактный класс его реализуют другие классы поддерживающие рисование т. ск. на себе. Он представляет интерфейс который можно использовать для выполнения рисования. Никаких данных graphics не хранит. Данные о том что прорисованно на компоненте сохраняет сам компонент, который объект графикс и предоставляет. Получив graphics объекта, вы просто получаете возможность рисовать на нем, не больше.  

Автор: dre 30.7.2006, 15:19
Согласен, об этом я почему-то совсем не подумал когда писал. Хорошо что есть такие люди которые поставят на путь истиный. 

Но проблема все равно остается, а время бежит неумолимо...
    

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