Program w języku Java

Celem zajęć będzie rozwinięcie prostego apletu - czyli programu osadzonego na stronie HTML

Program będzie bardzo podobny do poprzedniego napisanego w języku C++, również pojawi się w nim hierarchia Shape oraz ShapeFactory.

Tworzymy aplet

Projekt

Wybierz File → New → Java Project. Wprowadź ShapesApplet jako nazwę projektu.

Utworzony zostanie pusty projekt.

Klasa ShapesApplet

Wybierz File → New → Java Class

  • Wprowadź nazwę klasy ShapesApplet
  • Wprowadź nazwę pakietu pl.edu.agh.kis.snwo

Wprowadź metodę paint() i nie zapomnij o extends Applet. Metoda paint() zostanie wywołana za każdym razem, kiedy trzeba będzie przerysować okno apletu.

public class ShapesApplet extends Applet{
 
	/**
	 * 
	 */
 
	public void paint(Graphics g){
		g.drawLine(10, 10, 100, 100);
		g.drawLine(10, 100, 100, 10);
	}
}

Wybierz Run i jako konfigurację wskaż Run as applet. Uruchomione zostanie narzędzie appletviewer, a w nim narysowane dwie skrzyżowane linie.

  • Teoretycznie, można aplet uruchomić w oknie przeglądarki. Ale ostatnio polityka bezpieczeństwa wdrożona w przeglądarkach zaostrzyła się i z lokalnego dysku nie da się załadować apletu (przynajmniej bez zmiany domyślnych ustawień).
  • Po umieszczeniu apletu na serwerze HTTP, już jest to możliwe. Jeśli ktoś ma konto w UCI, powinno się udać http://www.uci.agh.edu.pl/porady-uci/#strona

Aby wyświetlić aplet w oknie przeglądarki, jego kod musi być osadzony na stronie HTML. Przykładowa strona wygląda następująco:

<html>
<head>
<title>Shapes Applet</title>
</head>
<body>
<applet code="pl.edu.agh.kis.snwo.ShapesApplet.class" width="1200" height="700" />
</body>
</html>

Po przesłaniu plików na serwer…

  • test.html
  • pl
    • edu
      • agh
        • kis
          • snwo
            • ShapeApplet.class

…i wybraniu odpowiedniego adresu w oknie przeglądarki aplet uruchomi się.

:!: Proszę zwrócić uwagę na rozmieszczenie plików. Każdy człon nazwy pakietu odpowiada katalogowi.

Dodajemy do apletu rysowanie wektorów

Dodajemy klasę Shape

Wybierz File → New → Java Class i jako nazwę klasy wprowadź Shape.

Klasa powinna trafić do pakietu pl.edu.agh.kis.snwo

package pl.edu.agh.kis.snwo;
 
import java.awt.Color;
import java.awt.Graphics;
 
public class Shape {
	Color c=Color.black;
	void draw(Graphics g){}
 
}

Dodajemy klasę Line

Wybierz File → New → Java Class i jako nazwę klasy wprowadź Line. Wprowadź w polu superclass (klasa bazowa) Shape.

Wprowadź kod:

package pl.edu.agh.kis.snwo;
 
import java.awt.Graphics;
 
public class Line extends Shape {
	int x1;
	int y1;
	int x2;
	int y2;
	void draw(Graphics g){
		g.setColor(c);
		g.drawLine(x1, y1, x2, y2);
	}
 
}

Dodajemy klasę Circle i Rectangle

  • Postępujemy analogicznie, jak poprzednio. Wybieramy takie same atrybuty jak dla programu w C++.
  • Podobnie implementujemy metody draw wywołując g.drawOval() oraz g.drawRect(). Proszę przeczytać ich opisy, aby poprawnie je wywołać.

Pierwsza refaktoryzacja

Nie podoba nam się występujące w trzech miejscach g.setColor( c ). Bardziej podobałoby się g.setColor(color).

Zmieniamy nazwę odziedziczonego atrybutu

  • Idziemy do Shape.java.
  • Zaznaczamy c i wybieramy Refactor→Rename….
  • Wprowadzamy nową nazwę color
  • W każdym miejscu zostanie zmieniona nazwa atrybutu.

Dodajemy ShapeFactory

Odtworzymy projekt klasy zaimplementowanej w języku C++

public class ShapeFactory {
	private ShapeFactory(){}
	private static ShapeFactory _theFactory = new ShapeFactory();
	static ShapeFactory get(){return _theFactory;}
 
	Shape createLine(int x1,int y1,int x2,int y2){
		Line s= new Line();
		s.x1=x1;
		s.x2=x2;
		s.y1=y1;
		s.y2=y2;
		return s;
	}
 
	Shape createCircle(int x,int y,int r){
        //...	
	}
	Shape createRectangle(int x1,int y1,int x2,int y2){
        //...	
        }
 
}

Jak poprzednio:

  • Konstruktor jest prywatny
  • Jest jedna statyczna instancja klasy
  • Metoda get() pozwala zrealizować do niej dostęp
  • Ponieważ operatorem zasięgu w Javie jest kropka, będziemy wołać ShapeFactory.get().createRandomShape()

Piszemy createRandomShape

W metodzie createRandomShape() była wołana funkcja rand(). Napiszemy ją, aby nie przerabiać kodu

	Random generator = new Random(System.currentTimeMillis());
 
	private int rand(){
		return generator.nextInt(1234567);
	}
 
	Shape createRandomShape(){
 
		int choice = rand()%3;
		switch(choice){
			case 0:
				return createLine(rand()%300,rand()%300,rand()%800,rand()%900);
			case 1:
				return createCircle(rand()%900,rand()%900,rand()%300);
			case 2:
				return createRectangle(rand()%300,rand()%300,rand()%800,rand()%900);
		}
		return null;
	}

Modyfikujemy kod apletu

  • Dodajemy tablicę referencji typu Shape o rozmiarze SIZE
	static final int SIZE = 100;
	Shape[]table = new Shape[SIZE];
  • W publicznym konstruktorze inicjujemy ją losowo wygenerowanymi wektorami
	public ShapesApplet(){
		for(int i=0;i<SIZE;i++){
			table[i]=ShapeFactory.get().createRandomShape();
		}
	}
  • Zmianiamy metodę paint(). Mam nadzieję, że rozpoznajecie Państwo konstrukcję foreach.
	public void paint(Graphics g){
		for(Shape s:table){
			s.draw(g);
		}
	}
Uruchamiamy

Dodajemy kolory

Oczywiście, mogliśmy od razu wprowadzić docelowy kod, ale celem jest zapoznanie się z możliwościami refaktoryzacji. Więc kolory dodajemy później…

Refaktoryzacja: dodawanie parametru do istniejącej funkcji

Poza losową generacją rozmiarów wektorów, chcemy, aby miały one losowo wybrane kolory. Funkcje createLine(), createRectangle() i createCircle() raczej nie powinny losować kolorów. Przekażemy je do nich jako parametr ustawiany w createRandomShape

  • Zaznacz metodę createLine() w kodzie ShapeFactory.
  • Wybierz Refactor→Change Method Signature…
  • Dodaj w nowy parametr metody Color color

  • Przejrzyj zmiany w kodzie createRandomShape()
  • Spróbuj zmienić kolejność parametrów (możesz to zrobić w dowolnym momencie). Proponuję, aby Color color pojawił się na początku.

Zmieniamy kod funkcji

Tak, jak poniżej – musimy coś z parametrem kolor zrobić.

	Shape createLine(Color color,int x1,int y1,int x2, int y2){
		Line s= new Line();
		s.color=color;
		s.x1=x1;
		s.x2=x2;
		s.y1=y1;
		s.y2=y2;
		return s;
	}

Wprowadzamy s.color=color; dla Rectangle i Circle.

Dodajemy losową generację kolorów

	Shape createRandomShape(){
		Color color = new Color(rand()%256,rand()%256,rand()%256); 
		int choice = rand()%3;
		switch(choice){
			case 0:
				return createLine(color,rand()%300,rand()%300,rand()%800, rand()%900);
			case 1:
				return createCircle(color,rand()%900,rand()%900, rand()%300);
			case 2:
				return createRectangle(color,rand()%300,rand()%300,rand()%800, rand()%900);
		}
 
		return null;
	}

i po uruchomieniu otrzymujemy…

Dystrybucja apletu

Tworzymy archiwum jar

Programy napisane w Javie z reguły są dystrybuowane w postaci archiwów jar. Nazwa jest luźno związana ze słoikiem ;-) Raczej jest to skrót od Java ARchive. W gruncie rzeczy jest to zwykły zip, w którym umieszczany jest skompilowany kod klas oraz (opcjonalnie) dodatkowe pliki zawierające klucze użyte do podpisu i sumy kontrolne plików class.

  • Dodaj folder do projektu i nazwij go build. Wybierz File→New→Folder
  • Wybierz opcję File→Export→Java→JAR File
  • W oknie dialogowym wybierz elementy do eksportu i docelowy folder

  • Plik JAR pojawi się w katalogu build

Dodajemy stronę HTML

W odróżnieniu od poprzedniego przykładu pojawił się atrybut archive=“ShapesApplet.jar”

<html>
<head>
<title>Shapes Applet</title>
</head>
<body>
<applet code="pl.edu.agh.kis.snwo.ShapesApplet.class" archive="ShapesApplet.jar" width="1200" height="700" />
</body>
</html>

Następnie otwieramy ją w przeglądarce. 8-o Niestety - nie udaje się uruchomić apletu? Nie pozwalają na to domyślne ustawienia przeglądarki.

Podpisujemy aplet

Zazwyczaj przeglądarka pozwala na uruchomienie podpisanego apletu, nawet przy użyciu testowego certyfikatu. Ten docelowy powinna wygenerować zaufana instytucja (i pobrać za to opłatę).

Podpisywanie pliku jar jest procesem dwuetapowym:

  • Wpierw generujemy testowy certyfikat użyty do podpisu za pomocą narzędzia keytool. (Musimy podać hasło, oraz możemy imie, nazwisko, nazwę instytucji, itp.)
  • Następnie osadzamy go w pliku JAR za pomocą narzędzia jarsigner
"c:/Program Files/Java/jdk1.6.0_31/bin/keytool.exe" -genkey -alias mojeid
"c:/Program Files/Java/jdk1.6.0_31/bin/jarsigner.exe" ShapesApplet.jar mojeid

Otwieramy lokalny plik w przeglądarce

Jeśli udało się wykonać poprzedni krok - możemy załadować plik do przeglądarki z lokalnego systemu plików. Możemy go także umieścić na serwerze HTTP (jesli mamy do niego dostęp).

swo/lab_2_eclipse_i_java.txt · Last modified: 2013/10/15 02:05 by pszwed
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0