Помощ при двойно буфериране

изображението

Правя програма, която трябва да рисува графики на отделен панел в същия прозорец като основната програма. Когато плъзгате тази графика с мишката, тя не трябва да трепти. За това използвах двойно буфериране. Направих го, както е описано в книгата за Java, но първо, изображението все още трепти, и второ, на панела, където трябва да се рисува графика, също е изчертан целият интерфейс на програмата: всички бутони и текстови полета. Кажете ми къде правя грешка в кода и как правилно да прилагам двойно буфериране в GUI приложения?

Повърхност - панелът, където се рисуват графики.

Вмъква се в основната програма по следния начин:

Код на класа на повърхността:

буфериране

Това означава, че пребоядисвате само самия компонент и забравяте да нарисувате неговия контейнер :exclamation Извикайте метода repaint() на контейнера, в който се намира целевият компонент и всичко ще бъде наред. Например, ако рисувате върху JPanel, който е върху JFrame, тогава извикайте repaint върху JFrame (или върху ContentPane на този JFrame). Той ще преначертае себе си и своите компоненти. ;-)

буфериране

изображението

помощ

изображението

MoonCat, къде да напиша repaint() за контейнера, в основната програма? Обяснете моля.

Най-добър код. Усмихни се

Публикувайте целия код на вашата програма.

изображението

Ето примерен код.

Рамка за изпълнение.

изображението

MoonCatкодът ти също не работи, ЧЕСТНО! Когато преместите синия квадрат на бял фон, всичко е наред. И когато опитате нещо по-сложно като

тогава изображението започва да трепти, когато го преместите или ако преместите целия прозорец. Специално проверих стандартните програми от jsdk. В тях всичко е наред. ?

помощ

Здравейте, ето кода, но в него има грешкитрябва да го поправиш!

Подобрение на изображението чрез двойно буфериране

Същността на двойното буфериране е, че в RAM се създава буфер - обект от класа на изображението или Bufferedimage и се извиква неговият графичен контекст, в който се формира изображението. На същото място буферът се изчиства, което също не се отразява на екрана. Едва след като изпълните всички стъпки, готовото изображение се показва на екрана.

Всичко това се случва в метода updateo, а методът paint извиква само update(). Списъци 10-15-15 обясняват тази техника.

Списък 15.10. Двойно буфериране с класа на изображението

публична невалидна актуализация (графика g)

int w = getSize().width, h = getSize().height;

// Създаване на буфер за изображения в RAM

Изображение offlmg = createlmage(w, h);

// Вземете неговия графичен контекст

Графика offGr = offImg.getGraphics();

// Промяна на текущия цвят на буфера на цвета на фона

//и запълнете прозореца на компонента с него, изчиствайки буфера

offGr.fillRect(0, 0, w, h);

// Възстановяване на текущия цвят на буфера

// За листинг 15.9 контекстуализирайте изображението

offGr.drawlmage(img[брой % 10], 0, 0, това);

// Рисуване в графичния контекст на буфера

// Показване на буферното изображение на екрана

// (може да се премести в метода paint())

g.drawlmage(offlmg, 0, 0, това); >

// Методът paint() не е задължителен

public void paint(Graphics g)J update(g); >

Списък 15.11. Двойно буфериране с класа Bufferedimage

публична невалидна актуализация (графика g)

Graphics2D g2 = (Graphics2D>,g;

int w = getSize().width, h = getSize().height;

// Създаване на буфер за изображения в RAM

буферирано изображение bi=(Буферирано изображение)createlmage(w, h);

// Създаване на контекст на графичен буфер

Graphics2D big = bi.createGraphics();

// Задайте цвят на фона

// Изчистване на буфер с фонов цвят

big.clearRect(0, 0, w, h);

// Възстановяване на текущия цвят

// Показване на нещо голямо в контекста на графиката

// Показване на буфера на екрана

g2.drawImage(bi, 0, 0, this);

Методът на двойно буфериране се е превърнал в де факто стандарт за извеждане на променящи се изображения и библиотеката Swing го използва автоматично.

Този метод е удобен и при преначертаване на отделни части от изображението. В този случай неизменната част от изображението се изчертава в буферното изображение, а в метода paint() това, което се променя при всяко преначертаване.

Листинг 15.12 показва втория начин на анимация - кадрите на изображението се изчертават директно в програмата, в метода update (), според дадения закон за промяна на изображението. В резултат на това червената топка отскача на фона на изображението.

Списък 15.12. Анимация чрез рисуване

импортиране на java.awt.event.*;

клас DrawAniml разширява Frame

частно изображение img;

private int брой;

MediaTracker tr = нов MediaTracker(това);

публична невалидна актуализация (графика g)

Graphics2D g2 = (Graphics2D)g;

int w = getSizeO.width, h = getSize().height;

Bufferedlmage bi = (Bufferedlmage)createlmage(w, h) ;

Graphics2D big = bi.createGraphics();

// Запълване на фона с img изображението

big.drawlmage(img, 0, 0, това);

// Задаване на цвят на чертеж

// Начертайте кръг в графичния контекст на буфера,

// движение по синусоида

big.fill(нов Arc2D.Double(4*брой, 50+30*Math.sin(брой),

50, 50, 0, 360, Arc2D.OPEN));

// промяна на цветарисунка

// Начертайте хоризонтална линия

big.draw(нова линия2D.Double(0, 125, w, 125));

// Показване на буферното изображение на екрана

g2.drawlmage(bi, 0, 0, това); >

public static void main(String[] args)

DrawAniml f = new DrawAniml(" Анимация");

public void windowClosing(WindowEvent ev)

Удобно е да се създаде ефект на трептене, цветни преливания, затъмняване и други ефекти, получени чрез замяна на отделни пиксели в изображение с помощта на класа Memoryimagesource. Методите newPixeis() на този клас карат изображението да бъде незабавно преначертано, дори без извикване на метода repaint(), ако методът setAnimated(true) е бил изпълнен предварително. Двата най-често използвани метода са:

newPixels(int x, int y, int width, int height) — правоъгълен фрагмент от изображението, посочено от аргументите, се изпраща до получателя; nevPixels() - цялото изображение се изпраща до получателя. Списък 15.13 показва този метод в употреба. Квадратът, показан на екрана, блести с различни цветове.

Списък 15.13. Анимация с MemorylmageSource

клас InMemory разширява Frame

private int w = 100, h = 100, брой;

private int[] pix = нов int[w * h];

частно изображение img;

int red = 255 * y / (h - 1);

int зелено = $25 * x / (w - 1);

mis = нов MemorylmageSource(w, h, pix, 0, w);

// Задайте възможност за анимиране

public void paint (Graphics gr)

gr.drawImage(img, 10, 30, това);

публична невалидна актуализация (графика g)

публична празнота има)

// Промяна на масива от пиксели според някакъв закон

pix[i++J = (255 " 24)(255 + 8 * брой " 16)

(8*броене "8) 255 + 8 * броене;

// Уведомете потребителя за промяната

public static void main(String[] args)

InMemory f= new InMemory("Изображение в паметта");

public void windowClosing(WindowEvent ev)

Това са всички средства за анимация, останалото е тяхното умело приложение. Комбинирайки разгледаните методи, можете да постигнете невероятни ефекти. Документацията на SUN J2SDK в директориите demo\applets и demo\jfc\Java2D \src предоставя много примери за аплети и приложения с анимация.