Створення Java-аплета для відображення географічних карт, Java, Програмування, статті

Олексій Смирнов

Багато починаючі Java-програмісти, після знайомства з базовими можливостями і методами створення Java-аплетів, пробують застосувати отримані знання для написання вже власних аплетів – невеликих програм, що додаються до веб-сторінці. Отже, якщо ви теж один із них, то сьогодні ми спробуємо разом створити свій нескладний аплет для відображення географічної карти. Метою створення цього додатка буде те, що часто потрібно розмістити план або карту того чи іншого об’єкта великих розмірів. І оскільки детальне зображення не буде вписуватися в дизайн і призведе до повільної завантаженні веб-сторінки, то більшість HTML-програмістів вдається до використання тега

, що дозволяє створити декілька “клікабельним” областей на зображенні. Ми ж, природно, відстанемо вірні Java і спробуємо створити аплет Map, який буде відображати загальний глобальний план і по клацанню миші завантажувати більш детальне зображення виділеної області карти. Так як карта у вас буде в кожного своя, то вельми розумно буде створити аплет, який буде можна легко налаштувати на будь-які зображення. Ви вже знаєте, що параметри аплета задаються в HTML-тегу , тому щоб наш приклад був корисніше для вас в освоєнні Java спробуємо для установки програми використовувати файл конфігурації. Така конструкція крім усього іншого дозволить “сховати” від цікавих очей “конструкцію” вашої карти і не дасть скопіювати файли зображень.

Тому перше, з чого ми мабуть почнемо проектування аплету – розробимо структуру файлу конфігурації. Отже, Map.dat буде містити назви графічних файлів різних частин карти і координати областей, де користувач по клацанню миші зможе отримати “збільшену” картинку. Слідуючи нашому технічному завданню Разоб’ем файл на дві частини: глобальний вид і детальні зображення з координатами. Отже, одержимо приблизно наступне:

# Global map picture
V0.jpg
# Map area definition
202 214 55 55 V1.jpg
202 159 55 55 V2.jpg
257 159 55 55 V3.jpg
257 214 55 55 V4.jpg
 92 214 55 55 V7.jpg
147 214 55 55 V8.jpg
147 159 55 55 V9.jpg
 92 159 55 55 V10.jpg

Лістинг 1. Файл Map.dat

Використовуючи знак “#” можна буде відділяти коментарі від решти змісту файлу.

Тепер почнемо проектувати безпосередньо сам Java-аплет. Створіть файл нашого майбутнього класу Map.java. І помістіть туди наступне:

import java.applet.*;
public class Map extends Applet
{
/**
 * Initialization.
 */
public void init()
{ / / Читати файл конфігурації / / Відобразити карту
}
}

Лістинг 2. Клас Map.java

Як бачите з коментарів (Лістинг 2) справа залишилася за малим: прочитати файл конфігурації і відповідно до отриманих значеннями відобразити карту. Почнемо з першого. Створимо метод getData () для читання файла конфігурації Map.dat. Для доступу до файлової системи (читання файлу) нам буде потрібно використовувати класи InputStream і StreamTokenizer з пакету java.io. Клас StreamTokenizer реалізує простий лескіческій сканер, який розбиває потік символів InputStream на лексеми (слова). Це корисно для нас так як наш файл Map.dat містить різні лексеми: координати областей у вигляді чисел і назви файлів. Створивши фільтр, можна скористатися методом nextToken () для читання лексем. Він повертає або символ, або константу: StreamTokenizer.TT_EOF, StreamTokenizer.TT_NUMBER, StreamTokenizer.TT_WORD. Фільтрацію коментарів, які у нас починаються з символу “#”, можна просто здійснити за допомогою методу commentChar ().

Текст методу буде наступним:

/**
 * Read the data file Map.dat.
 */
protected void getData()
{
InputStream is=null;
int i=0;
int ix=0;
int x=0,y=0,w=0,h=0;
try
{
	try
	{
	is = new URL(getCodeBase(), 
		"Map.dat").openStream();
	StreamTokenizer st = 
		new StreamTokenizer(is);
	st.eolIsSignificant(false);
	st.commentChar('#');
	while (st.ttype != 
		StreamTokenizer.TT_EOF)
	{
		st.nextToken();
		if (st.ttype==st.TT_NUMBER)
		{
		int  n = (int) st.nval;
		switch (i)
		{
		case 0:
			x = n;
			break;
		case 1:
			y = n;
			break;
		case 2:
			w = n;
			break;
		case 3:
			h = n;
			break;
		}
		i++;
		if (i==4)
		{
		lPoint[ix] = new Point(x,y);
		rPoint[ix] = new Point(w,h);
		i=0;
		}
		//continue;
		}
		if(st.ttype==st.TT_WORD)
		{
			mapFile[ix]=st.sval;
			ix++;
		}
	}	/* while */
}
catch (MalformedURLException e) {}
}
catch (IOException e) {}
count=ix;
}

Лістинг 3. Метод getData ()

Ви повинні були помітити, що в наведеному коді зустрілися ще непояснені поля lPoint і rPoint. Це масиви класу Point в яких ми будемо зберігати точки, лічені з файлу. Клас Point, описаний як частина пакета awt, являє собою структуру даних, яка може зберігати координати X, Y. mapFile – рядковий масив для зберігання імен файлів.

Тепер приступимо до getMap (). Як параметр виклику цього методу буде ім’я файлу pic, який потрібно показати. Після завантаження картинки не забудемо перемалювати аплет за допомогою repaint ();

/**
 * Get file of map picture from URL.
 */
private void getMap(String pic)
{
	map = getImage(getCodeBase(), pic);
	repaint();
}
/**
* Update applet.
**/
public void update(Graphics g)
{
	paint(g);
}
public void paint(Graphics g)
{
	g.drawImage(map,0,0,this);
	g.setColor(Color.black);
	g.drawRect(0,0,size().width-1,
		size().height-1);
	if (!isZoom & curId!=0)
	{
		g.setColor(Color.red);
		g.drawRect(lPoint[curId].x,
			lPoint[curId].y,
			rPoint[curId].x,
			rPoint[curId].y);
	}
}

Лістинг 4. Методи getMap (), update () і paint ()

Для перемикання між загальним і детальним планом будемо використовувати булеву змінну isZoom, яка буде true, тоді коли нам буде потрібно збільшувати нашу карту, тобто показати картинку детального плану. Збільшення / зменшення буде відбуватися за допомогою клацання миші по карті. Для того, щоб користувач, який використовує наш аплет, зміг визначити куди йому натискати (можливо, що не всі області загального плану можна буде збільшити), при наведенні курсору миші на “клікабелье” область будемо показувати її прямокутну рамку червоного кольору. Таким чином вам залишилося тільки додати методи, які будуть відповідати за обробку подій миші.

public boolean mouseUp(Event evt, int x, int y)
{
	if (isZoom)
	{
		isZoom=false;
		getMap(mapFile[0]);
	}
	else
	{
	if (curId == 0)
	{
	showStatus("This area have not zoom.");
	}
	else
	{
	isZoom=true;
	getMap(mapFile[curId]);
	}
	}
	return true;
}
	
public boolean mouseMove(Event evt, int x, int y)
{
	int i;
	i = getIndex(x,y);
		
	if (!isZoom)
	{
	if (curId != i)
	{
		if (curId != 0)
			repaint(lPoint[curId].x,
		lPoint[curId].y,rPoint[curId].x+1,
		rPoint[curId].y+1);
		if (i != 0)
			showArea(i);
		curId = i;
	}
	}
	return true;
}
/**
 * Show area under mouse pointer.
 **/
private void showArea(int i)
{
	Graphics g = null;
	g = this.getGraphics();
	g.setColor(Color.red);
	g.drawRect(lPoint[i].x,
		lPoint[i].y,
		rPoint[i].x,
		rPoint[i].y);
}
/**
 * Get index of map image.
 **/
private int getIndex(int x, int y)
{
	for (int i=1; i=lPoint[i].x 
		& x<=(lPoint[i].x+rPoint[i].x) 
		& y>=lPoint[i].y 
		& y<=(lPoint[i].y+rPoint[i].y))
	return i;
	return 0;
}

Лістинг 5. Обробка подій миші

Ну і нарешті, зробимо більш дружній інтерфейс - додамо простий метод, який буде відображати повідомлення в рядку статусу браузера.

/**
 * Show message in status line.
 **/
private void zoomStatus()
{
	String msg;
	if (isZoom)
		msg="Click for unzoom";
	else
		msg="Click for zoom";
	showStatus(msg);
}

Лістинг 5. Метод zoomStatus ()

Тепер, природно, не забувши додати всі поля та класи, які використовуємо, отримаємо наступне:

import java.awt.*;
import java.awt.image.*;
import java.applet.*;
import java.net.*;
import java.io.*;
public class Map extends Applet
{
int max=100;
Image map;
int count;
										   
Point lPoint[];
Point rPoint[];
String mapFile[]=new String[max];
	
int curId;
boolean isZoom;
/**
 * Initialization.
 */
public void init()
{
	lPoint = new Point[max];
	rPoint = new Point[max];
	getData();
	getMap(mapFile[0]);
}

Лістинг 6. Остаточний вигляд початку файлу класу

Після компіляції код і отримавши файл аплета Map.class спробуємо викликати його з HTML-сторінки. Виклик класу зі сторінки буде наступним:

<applet code=Map.class width=400 height=400>
</applet>

Не забудьте помістити файли вашої картки в той же каталог, де знаходяться аплет, HTML-сторінка і Map.dat.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*