Rysowanie własnych figur

0

Witam,

Mam pytanie dotyczące rysowania figur w Javie.
Otóż stworzyłem sobie klasy Kwadrat, Trójkąt itp. Figury te reprezentowane są przez punkty: np. kwadrat ma punkty a, b, c, d. Mam metody do translacji, obrotu i skalowania, które robią transformacje na punktach. No i teraz pytanie w jaki sposób narysować te figury mając współrzędne punktów zapisane w typie Point2D?

Widziałem przykłady, w których rysowało się za pomocą obiektu Graphics i metody draw(). Czy zatem też muszę postąpić w ten sposób i po prostu funkcją draw() dorysowywać linie pomiędzy odpowiednimi punktami? Czy też może istnieje jakiś lepszy sposób?

Z góry dzięki za odpowiedź.

0

Klasa wielokąta w awt - http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Polygon.html

a potem już tylko Graphics g; g.drawPolygon(Polygon) lub g,drawPolygon(int[], int[], int)

ewentualnie do rysowania koła: Graphics g; g.drawArc(int, int, int, int, int, int)

0

Ach nie powiedziałem wszystkiego w pierwszym poście. Podałem tylko przykładowe figury, które akurat były wielokątami, więc klasa Polygon idealnie się do tego nadaje. Ale są jeszcze inne figury, które nie są zamknięte. Rozumiem, że w takiej sytuacji najlepiej jest skorzystać z g.drawLine(x,y).

Podczas próby rysowania pojawił się kolejny problem. Chciałbym, żeby po wciśnięciu przycisku coś się narysowało na moim wyświetlaczu. Postanowiłem użyć klasy JEditorPane jako wyświetlacza (nie wiem czy to dobry wybór). No i powiedzmy dodaję obsługę kliknięcia dla przycisku i w funkcji ActionPerformed chcę, żeby na JEditorPane coś się narysowało (powiedzmy linia). Niby jest metoda JEditorPane.paintComponents(Graphics g), ale nie bardzo wiem jak stworzyć obiekt klasy Graphics skoro klasa ta jest abstrakcyjna. Jak należy używać takiej klasy?

Z góry dzięki za odpowiedź

0

Lepsza, imo, do rysowania jest klasa JPanel, obiektu Graphics nie tworzysz, Ty tylko nadpisujesz metodę paintComponent() i nigdy jej nie wywołujesz. Ona jest wywoływana przez JVM, jeżeli chcesz zmienić rysunek, to wywołujesz metodę bezargumentową repaint().
W klasie Graphics jest metoda drawPolyLine() do rysowania łamanych.

0

A w którym miejscu powinienem nadpisać tę metodę? Póki co mam całe GUI zrobione za pomocą Visual Editor w Eclipse. Wygląda to mniej więcej tak, że jest klasa GlownaRamka, która dziedziczy z klasy JFrame. W klasie tej tworzone są obiekty np. panel przycisków, czy panel wykreślacza. Np. dla JEditorPane wygląda to tak:

/**
 * This method initializes jEditorPane	
 * 	
 * @return javax.swing.JEditorPane	
 */
private JEditorPane getJEditorPane() {
	if (jEditorPane == null) {
		jEditorPane = new JEditorPane();
		jEditorPane.setBounds(new Rectangle(9, 22, 375, 277));
	}
	return jEditorPane;
}

Wydaje mi się, że w takim przypadku nie da się nadpisać tej metody, bo trzeba by mieć osobną klasę, która dziedziczy po klasie zawierającej metodę paintComponent(Graphics g). Nie wiem czy robię to w dobrym kierunku, ale wymyśliłem coś takiego:

class RysujLinie extends JComponent{
	
	RysujLinie(int x1, int y1, int x2, int y2){
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
	}
	
	public void paintComponent(Graphics g){
		Graphics2D g2 = (Graphics2D)g;
		
		g2.drawLine(x1, y1, x1, x2);
	}
	
	int x1, y1;
	int x2, y2;
}

Czyli utworzyłem klasę, która ma przesłoniętą metodę paintComponent, w tym wypadku rysującą linię o zadanych punktach. I teraz jak mam metodę, która obsługuje akcję przycsku:

	private JButton getLiniaButton() {
		if (LiniaButton == null) {
			LiniaButton = new JButton();
			LiniaButton.setBounds(new Rectangle(15, 22, 94, 26));
			LiniaButton.setText("Linia");
			LiniaButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()

					RysujLinie component = new RysujLinie(20, 20, 50, 50);
					//add(component);
					jEditorPane.add(component);
				}
			});
		}
		return LiniaButton;
	}

Czy coś takiego ma szansę zadziałać, czy raczej nie o to w tym chodziło?

0

Masz zupełnie niewłaściwe podejście do rysowania.
Coś się tak uparł przy JEditorPane? Ja sam nigdy nie rysowałem po JEditorPane, ale zapewne można.

class MojUlubionyPanelDoRysowania extends JEditorPane //extends JPanel
{
     public MojUlubionyPanelDoRysowania
     {
          setBounds(new Rectangle(9, 22, 375, 277));
     }
     public paintComponent(Graphics g)
     {
          super.paintComponent(g);
           //tu jest rysowanie
     }
}
0

Zobacz też ostatni post w tym http://4programmers.net/Forum/622723?h=paintComponent#id622723 wątku. Zobaczysz jak można w różnych momentach rysować różne rzeczy.

0

Chyba rozumiem sposób w jaki to robisz. Mam tylko jedną wątpliwość. Bo w tej klasie, w której rysujesz robisz sobie zmienną parent typu głównej klasy. Gdzieś chyba czytałem, że nie jest to najlepszy sposób, bo w zasadzie Tobie jest potrzebna jedna metoda z tej klasy: getAction(). A co jeśli główna klasa jest dosyć rozbudowana? Do każdej klasy trzeba przekazać klasę główną? Wydaje się to trochę pamięciożerne, chyba, że o czymś nie wiem.

0

Jak sobie wyobrażasz współpracę dwóch klas bez wymiany referencji?
Wielkość zmiennej parent w klasie MyCanvas nie zależy od skomplikowania klasy A, jest to bowiem referencja (32 bajty). Trudno to uznać, za pamięciożerne.

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