Thread View: pl.comp.lang.java
6 messages
6 total messages
Started by zoska
Sat, 22 Oct 2011 09:19
java 2D i znikajacy rysunek
Author: zoska
Date: Sat, 22 Oct 2011 09:19
Date: Sat, 22 Oct 2011 09:19
75 lines
3290 bytes
3290 bytes
Witam
Napisalem taki maly programik w ktorym po kliknieciu buttonu OK
pojawiaja sie dodatkowy zolty kwadrat. Po przyslonieciu i odslonieciu
tego okna jakims innym oknem np mozilla zostaje tlo ale kwadrat znika.
Pytanie jest takie: jak to zrobic zeby ten kwadrat nie zniknal ?
Dzieki za wszelkie sugestie
Ponizej kod programu:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class PaintBackground extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
setBackground(Color.BLACK);
g2d.setColor(Color.RED);
g2d.drawRect(60,60,150,150);
}
}
class CreateGUI implements MouseListener {
JFrame frame = null;
JPanel panel = new JPanel();
JButton button = null;
final static int sizeX = 400;
final static int sizeY = 400;
final static int locX = 10;
final static int locY = 10;
public CreateGUI() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(sizeX,sizeY);
frame.setLocation(locX,locY);
Container cont = frame.getContentPane();
cont.setLayout(new BorderLayout());
button = new JButton("OK");
button.addMouseListener(this);
cont.add(button, BorderLayout.NORTH);
panel.setLayout(new BorderLayout());
panel.add(new PaintBackground(), BorderLayout.CENTER);
cont.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
}
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
Graphics g = panel.getGraphics();
g.setColor(Color.YELLOW);
g.drawRect(40,40,90,90);
panel.revalidate();
}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
public class RunApp {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
public void run() {
new CreateGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
Re: java 2D i znikajacy rysunek
Author: nullpointer
Date: Sat, 22 Oct 2011 10:24
Date: Sat, 22 Oct 2011 10:24
32 lines
2014 bytes
2014 bytes
Za odrysowywanie komponentu odpowiada metoda paintComponent, co jak
widzę już wiesz. W twoim przypadku paintComponent rysuje tylko tło, a
już dodatkowego kwadratu nie - dodatkowy kwadrat rysujesz w mousePressed.
Problem w tym, że jak zasłonisz swój komponent innym oknem, to po jego
odsłonięciu wywoła się paintComponent (tak to działa w AWT/Swing), ale
już mousePressed nie, wiec narysuje się od nowa tylko to, co
zaimplementowałeś w paintComponent.
Spróbuj tak:
- zadeklaruj sobie flagę zawiadującą rysowaniem tego kwadratu:
/* początkowo go nie rysujemy */
private boolean isYellowRectVisible = false;
- w paintComponent zrób sobie ifa:
if (isYellowRectVisible) { /* rysowanie żłótego kwadratu */ }
- w mousePressed, zamiast rysować, ustawiaj sobie że chcesz,
aby ten kwadrat się rysował
isYellowRectVisible = true;
po czym wymuś odrysowanie komponentu metodą repaint().
Polecam też lekturkę poniższego:
http://java.sun.com/products/jfc/tsc/articles/painting/
http://download.oracle.com/javase/tutorial/uiswing/painting/
--
npe
Re: java 2D i znikajacy rysunek
Author: zoska
Date: Sun, 23 Oct 2011 09:59
Date: Sun, 23 Oct 2011 09:59
8 lines
1645 bytes
1645 bytes
dzieki za sugestie. Pomysl wydaje sie byc interesujacy chociaz wydaje sie ze musi byc inny sposob zapamietania zawartosci okna. Wyobrazmy sobie aplikacje gdzie np po kliknieciu myszy w dowolny obszar rysunku rysuje sie kwadrat ze srodkiem w miejscu klikniecia. I powiedzmy ze takich kwadratow mamy bardzo duzo. W jaki sposob w takim przypadku zapamietac zawartosc okna ? Dzieki za pomoc
Re: java 2D i znikajacy rysunek
Author: nullpointer
Date: Sun, 23 Oct 2011 14:51
Date: Sun, 23 Oct 2011 14:51
21 lines
1856 bytes
1856 bytes
W dniu 2011-10-23 11:59, zoska pisze: > [ciach] W jaki sposob w takim przypadku > zapamietac zawartosc okna ? W podobny. Tak jak napisałem, rysowanie odbywa się w paintComponent i tylko to co masz tam zaimplementowane będzie odświeżane przy odrysowaniu okna. Jeśli chcesz panować nad tym co się tam dzieje, to dobrą praktyką jest stworzyć sobie "model danych". W opisanym przez Ciebie przypadku takim modelem może być ArrayList<Rectangle>. Klikając w komponent generujesz zdarzenie mousePressed, które nie rysuje, tylko modyfikuje model i powiadania Swinga o tej modyfikacji aby odrysował okno. Modyfikacja modelu polega w tym przypadku na dodaniu nowej instancji klasy Rectangle do ArrayListy. Natomiast w paintComponent "rysujesz model", czyli iterujesz po elementach ArrayListy i rysujesz poszczególne wielokąty. -- npe
Re: java 2D i znikajacy rysunek
Author: sielim
Date: Sun, 23 Oct 2011 17:04
Date: Sun, 23 Oct 2011 17:04
113 lines
3903 bytes
3903 bytes
Uzytkownik "zoska" <klociaciocia@gmail.com> napisal w wiadomosci
news:3314ac17-cdaa-4834-8d4c-8fac287f6083@h5g2000vbf.googlegroups.com...
Generalnie takie rzeczy robi sie w ten sposób, ze wszystko rysujesz do
bufora (zobacz
takie cus jak np. ImageBuffer), a w metodzie paint nie rysujesz tla, tylko
kopiujesz na ekran
odpowiedni fragmencik (zadany Rectangle) ze swojego bufora roboczego.
Ponizej masz przyklad klasy pomocniczej, która to wykorzystuje.
Do Twoich celów mozesz w ogóle wywalic metode 'render' i atrybut
renderOK.
A poza tym, to nic nie rysujesz w paincie (tam postawiasz kopiowanie
z buffered imege'a), tylko jak cokolwiek chcesz wrzucic na ekran,
to piszesz do obiektu bi.getGraphics() ( tak, jak tu w paincie robi to
render() )
i ew. repaint() na panelu.
Powodzenia :)
package pl.org.sielim.swing;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
/**
* Panel wspomagajacy podwójne buforowanie.
* Jak tego uzywac ? - patrz metody render i setRenderOK
*
* @author filip
*/
public class BufferedPanel extends JPanel {
public BufferedPanel() {
}
/** Metoda tworzaca obraz. Do pokrywania - definiujemy wlasny
* sposób rysowania panelu.
* Domyslnie po prostu wypelnia panel kolorem tla.
* @param gdc
* @param d
*/
protected void render(Graphics gdc, Dimension d) {
gdc.setColor(this.getBackground());
gdc.fillRect(0, 0, d.width, d.height);
}
/** Z pomoca tej metody sygnalizujemy (false),
* ze zawartosc bufora jest nieaktualna
* i nalezy obraz wyrenderowac od nowa.
* Zawsze, kiedy uznalemy, ze trzeba renderowac od nowa,
* stosujemy sekwencje wywolan:
* setRender(false);
* repaint();
* @param v
*/
public void setRenderOK(boolean v) {
this.renderOK = v;
}
/** Przydaje sie - jak np. bawimy sie w klikanie mysza i pozycjonowanie,
skalowanie itp.
* @return
*/
public Dimension getImgSize() {
return this.bisize;
}
/****************************************/
private boolean renderOK;
public void paint(Graphics gdc) {
super.paint(gdc);
Dimension d = this.getSize();
//System.out.println("BIP paint " + d + "==" + this.getImgSize());
if (d != null) {
if ((bi == null) || !d.equals(this.getImgSize())) {
this.bisize = d;
System.out.println("create image !");
this.bi = this.createImage(d);
}
if (!this.renderOK) {
//System.out.println("render !");
this.render(bi.getGraphics(), d);
this.setRenderOK(true);
}
gdc.drawImage(bi, 0, 0, null);
}
}
private BufferedImage bi;
private BufferedImage getBufImage() {
return this.bi;
}
private void setBufImage(BufferedImage b) {
this.bi = b;
}
private Dimension bisize;
private BufferedImage createImage(Dimension d) {
BufferedImage bimg = (BufferedImage) createImage(d.width, d.height);
this.setRenderOK(false);
return bimg;
}
}
Re: java 2D i znikajacy rysunek
Author: nullpointer
Date: Sun, 23 Oct 2011 19:01
Date: Sun, 23 Oct 2011 19:01
23 lines
1701 bytes
1701 bytes
> Generalnie takie rzeczy robi sie w ten sposób, ze wszystko rysujesz do > bufora [ciach] To ja tylko dorzucę od siebie, że "to zależy". Trzymanie bufora ma dwa zasadnicze minusy: 1. Trzymasz w ramie obrazek, co zajmuje tego ramu trochę. 2. Nie możesz usunąć obiektu (w podanym przypadku - np. "odklikując" go aby zniknął) Dla jasności, moja metoda też nie jest perfekcyjna, bo wymaga ciągłego odrysowywania, co przy obiektach bardziej skomplikowanych niż prostokąty może się okazać niewydajne. Tak więc, metodę dobierasz do tego, co aktualnie implementujesz. W przypadku opisanym przez zoske poszedłbym jednak moją ścieżką - mimo wszystko wydaje mi się poprawniejsza (a cache'owany BufferedImage potraktowałbym jako fajny hack do specjalnych zastosowań). -- npe
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads