Problem z projektem "coś jak Paint"

0

Witam,

Z programowania jestem zielony ale staram się nadrabiać braki. Na programowanie muszę zrobić projekt trochę podobny do popularnego paint'a. Za myszką z wciśniętym klawiszem ma się pojawiać ciag kwadracików, ktore będą w różnych kolorach.
Mój problem polega wlasnie na zmianie tych kolorów.
Rysuje używając

getGraphics().fillRect(x,y,10,10);

w metodzie mouseDragged.
Kolor próbowałem zmieniać

getGraphics().setColor(Color.BLUE);

ale to nie działa.
Moje pytanie brzmi: Jakiej funkcji użyć zeby zmienić kolor rysowanych kwadracików i jak zrobic żeby ten kolor zmieniał się losowo co np. 2 sek?
Z góry dzięki z odp.

0
  1. Najpierw setColor
  2. Potem fillRect

Jeśli nie działa, to pokaż cały kod.

Żeby kwadraciki się zmieniały, to:

  1. zamiast je rysować w mouseDragged musisz umieszczać info ich współrzędnych np. w ArrayLiscie
  2. rysowanie w paintComponent
  3. rysowanie (tamże) kwadracików o określonym kolorze
  4. co dwie sekundy zmiana koloru (zależnie od efektu, który chcesz osiągnąć można to zrobić różnie, np. możesz trzymać kolor jako parametr opisujący kwadracik w ArrayLiscie)
0

Najpierw musisz zrobić setColor() a potem malować.

0

Umieszam setColor przed fillRect... Bez rezultatu.
Wklejam cały program. (oprócz rysowania wyswietla jeszcze współrzędne myszki)

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

public class projekt extends JApplet implements MouseListener, MouseMotionListener
{
String tekst = " ";
        int x;
        int y;
    public void init()
    {
        addMouseListener(this);
        addMouseMotionListener(this);
    }
    public void start(){}
    public void stop(){}
        public void mouseDragged(MouseEvent evt)
    {

        x=evt.getX();
        y=evt.getY();
        tekst = "Przycisk wciśnięty, ";
        tekst += "współrzędne: x = " + evt.getX() + ", ";
        tekst += "y = " + evt.getY();
        getGraphics().setColor(Color.RED);
        getGraphics().fillRect(x,y,10,10);
    }
    public void paint(Graphics gDC)
    {
        gDC.clearRect(0, 0, getSize().width, getSize().height);
        gDC.drawString(tekst, 20, 20);


    }
    public void mouseClicked(MouseEvent evt)
    {
        int button = evt.getButton();
        switch(button){
            case MouseEvent.BUTTON1 : tekst = "Przycisk 1, ";break;
            case MouseEvent.BUTTON3 : tekst = "Przycisk 2, ";break;
            case MouseEvent.BUTTON2 : tekst = "Przycisk 3, ";break;
            default : tekst = " ";
        }
        tekst += "współrzędne: x = " + evt.getX() + ", ";
        tekst += "y = " + evt.getY();
        repaint();
    }
    public void mouseEntered(MouseEvent evt){}
    public void mouseExited(MouseEvent evt){}
    public void mousePressed(MouseEvent evt){}
    public void mouseReleased(MouseEvent evt){}
    public void mouseMoved(MouseEvent evt){}
    public void destroy(){}
    public String getAppletInfo()
    {
        return "Title:   \nAuthor:   \nA simple applet example description. ";
    }
    public String[][] getParameterInfo()
    {
        String paramInfo[][] = {
                 {"firstParameter",    "1-10",    "description of first parameter"},
                 {"status", "boolean", "description of second parameter"},
                 {"images",   "url",     "description of third parameter"}
        };
        return paramInfo;
    }
}
0

Koledzy i Koleżanki mam podobny problem i już kilka dni się męczę. Prosze bardzo o pomoc w imieniu swoim i użytkownika wyżej.

0
        getGraphics().setColor(Color.RED);
        getGraphics().fillRect(x,y,10,10);

W pierwszym wierszu używasz innego obiektu typu Graphics niż w drugim. Powinno być tak:

        Graphics g = getGraphics();
        g.setColor(Color.RED);
        g.fillRect(x,y,10,10);

Druga sprawa, nie rysujesz w metodzie paint(), zatem Twoje rysunki są nietrwałe. Użytkownik zmieni zakładkę w przeglądarce lub wyciągnie na wierzch inny program a potem wróci do apletu. Rysunku nie ma.

0

Jak należy to robić?

  1. Używać eventów mousePressed, mouseReleased i mouseMoved. Dwóch pierwszych do rejestracji stanu klawiszy, ostatniego do obsługi wleczenia mając wciśnięty przycisk(i).
  2. Żadnego rysowania czy zmiany na urządzeniu graficznym w obsłudze zdarzeń. Jedyną instrukcją związaną z generowaniem grafiki w metodach obsługi zdarzeń może być repaint(). Całkowite odrysowanie wyłacznie w paint lub paintComponent.
  3. start() powinno odrysować wszystkie ruchy myszą zachowane wcześniej w tablicach/listach. Przykrycie i odkrycie okienka przeglądarki/applet viewera nie powinno nigdy kasować tego co się narysowało kiedy aplet był na wierzchu.

Wtedy problemów z kolorami (i innych) nie będzie.

0

Bardzo prosta (i migająca) implementacja (na bazie powyższej):

import java.awt.event.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.*;

public class projekt extends JApplet implements MouseListener,
		MouseMotionListener {
	public class MyRect {

		private int y;
		private int x;
		private Color color;

		public int getY() {
			return y;
		}

		public int getX() {
			return x;
		}

		public Color getColor() {
			return color;
		}

		public MyRect(int x, int y, Color color) {
			this.x = x;
			this.y = y;
			this.color = color;
		}

	}

	String tekst = " ";
	int x;
	int y;
	private ArrayList<MyRect> rects = new ArrayList<MyRect>();
	Random r = new Random();

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

	public void start() {
	}

	public void stop() {
	}

	public void mouseDragged(MouseEvent evt) {

		x = evt.getX();
		y = evt.getY();
		tekst = "Przycisk wciśnięty, ";
		tekst += "współrzędne: x = " + evt.getX() + ", ";
		tekst += "y = " + evt.getY();

		Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
		rects.add(new MyRect(x, y, c));
		repaint();
	}

	public void paint(Graphics gDC) {
		gDC.clearRect(0, 0, getSize().width, getSize().height);
		gDC.drawString(tekst, 20, 20);
		for (MyRect r : rects) {
			gDC.setColor(r.getColor());
			gDC.fillRect(r.getX(), r.getY(), 10, 10);
		}
	}

	public void mouseClicked(MouseEvent evt) {
		int button = evt.getButton();
		switch (button) {
		case MouseEvent.BUTTON1:
			tekst = "Przycisk 1, ";
			break;
		case MouseEvent.BUTTON3:
			tekst = "Przycisk 2, ";
			break;
		case MouseEvent.BUTTON2:
			tekst = "Przycisk 3, ";
			break;
		default:
			tekst = " ";
		}
		tekst += "współrzędne: x = " + evt.getX() + ", ";
		tekst += "y = " + evt.getY();
	}

	public void mouseEntered(MouseEvent evt) {
	}

	public void mouseExited(MouseEvent evt) {
	}

	public void mousePressed(MouseEvent evt) {
	}

	public void mouseReleased(MouseEvent evt) {
	}

	public void mouseMoved(MouseEvent evt) {
	}

	public void destroy() {
	}

	public String getAppletInfo() {
		return "Title:   \nAuthor:   \nA simple applet example description. ";
	}

	public String[][] getParameterInfo() {
		String paramInfo[][] = {
				{ "firstParameter", "1-10", "description of first parameter" },
				{ "status", "boolean", "description of second parameter" },
				{ "images", "url", "description of third parameter" } };
		return paramInfo;
	}
}
0

Dzieki za wszystkie odp i pomoc.
Ma ktoś pomysł jak zrobić zeby okienko całe nie mrugało przy poryszaniu myszki?

0

Dwa tryby rysowania: wszystko lub tylko ostatni kwadracik

        ...
        int x;
        int y;
        private boolean all = true;
        private ArrayList<MyRect> rects = new ArrayList<MyRect>();
        ...
        public void mouseDragged(MouseEvent evt) 
        {
                all = false;
                x = evt.getX();
                y = evt.getY();
                tekst = "Przycisk wciśnięty, ";
                tekst += "współrzędne: x = " + evt.getX() + ", ";
                tekst += "y = " + evt.getY();
 
                Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
                rects.add(new MyRect(x, y, c));
                repaint();
        }
        public void paint(Graphics gDC) 
        {
            if(all)
            {                
                gDC.clearRect(0, 0, getSize().width, getSize().height);
                gDC.drawString(tekst, 20, 20);
                for (MyRect r : rects) {
                        gDC.setColor(r.getColor());
                        gDC.fillRect(r.getX(), r.getY(), 10, 10);
                }
            }
            else
            {
                MyRect r = rects.get(rects.size()-1);
                gDC.setColor(r.getColor());
                gDC.fillRect(r.getX(), r.getY(), 10, 10);
            }            
        }
        public void mouseReleased(MouseEvent evt) 
        {
            all = true;
        }
0

Dzięki jeszce raz.
Ostatnia sprawa. Chcę żeby przy kliknięciu prawym klaiwszem myszy był czyszczony obraz. Próbowałem czegoś takiego :

 if (button == MouseEvent.BUTTON3) {g.setColor(Color.white); g.fillRect(0,0, getSize().width, getSize().height);}

w mouseClicked albo mousePressed
ale nie przynosi to oczekiwanego przeze mnie efektu.
Jak inaczej to zrobic?

0

A było mówione:
"2. Żadnego rysowania czy zmiany na urządzeniu graficznym w obsłudze zdarzeń. Jedyną instrukcją związaną z generowaniem grafiki w metodach obsługi zdarzeń może być repaint(). Całkowite odrysowanie wyłacznie w paint lub paintComponent."

1
  1. Nie rysuj w metodach obsługi zdarzeń.
  2. "Opróżnij" kolekcję kwadratów:
  rect.clear();
  repaint();

Pozostanie napis, jeśli czasami ma on być a czasami nie, to dodaj jeszcze jedną flagę logiczną decydującą czy wyświetlać napis.

0

Przepraszam, że wam tak zawracam głowę ale nie wychodzi mi. Mam to zrobic w paincie tak?
Ale tak jak wczesniej robiłem z ifem? Próbuję :

            int button = evt.getButton();
            if (button == MouseEvent.BUTTON3) {  
                rect.clear();
                repaint();}

ale mi nie kompiluje i podkreśla "evt" w

 int button = evt.getButton();

i pisze komunikat "cannot find symbol" chociaż dalej przy wyswietlaniu napisów taka funkcja działa.

0

Ech... a czym niby w paint() miało by być evt ? ;p Masz tam taki parametr ? Zmienną ? Cokolwiek ? Nie masz, zatem podświetla ;p Powinno być tak, że tam, gdzie to robiłeś powinieneś ustawiać jakąś flagę (zmienną typu boolean) a w paint() sprawdzać czy jest ona ustawiona i jeśli tak, to wywoływać clear().

0

Ech. To co Ci Bogdans podpowiedział miałeś zrobić w procedurze obsługi myszy. Przecież jak wyczyścisz sobie listę rects, to będzie ona pusta, a więc w paint pętla for w ogóle się nie wykona, a wcześniej odpali się clearRect, która wypełni cały obszar kolorem tła (czyli po prostu wymaże to co było). Lista rects jest Twoim stanem programu, który zmieniasz w procedurach obsługi myszy. Natomiast paint z tego stanu wyłącznie korzysta, czyli wyrysowuje listę kwadratów lub nie wyrysowuje. Każda rzecz robi tylko swoje.

Gdybyś miał to samo zrobić dla dowolnych rzeczy jakie sobie wymalujesz myszą, to musiałbyś użyć pojemnika takiego jak np. List<Maźnięcie>, gdzie Maźnięcie powinno być zdefiniowane jako obiekt przechowujący listę klikanych bądź wleczonych punktów, rodzaj figury (linii), kolor, średnica itp. - czyli "nagrany" cały ruch myszą jakimś narzędziem od wciśnięcia do puszczenia klawisza myszy. Wtedy w paint miałbyś pętlę odrysowującą kolejne "maźnięcia", a w niej ustawienie figury, koloru, kształtu, a następnie znowu w pętli odrysowanie figur pod kolejnymi punktami. To w paint.

Natomiast w czasie takiego "nagrywania" (czyli podczas wleczenia) w obsłudze mouseMove używa się instrukcji repaint z argumentem będącym prostokątem okalającym miejsce aktualnego położenia myszy - tak aby nie odrysowywać wszystkiego co się da przy każdym kolejnym przesunięciu myszy, a tylko to co się "domalowało". Natomiast kiedy okienko takie zostanie zasłonięte i ponownie odsłonięte, to system wywoła sobie repaint na wszystko lub na cały odkryty obszar i wtedy paint przy najbliższej okazji to wykona.

1 użytkowników online, w tym zalogowanych: 0, gości: 1