下のプログラムは作成の緒についたばかりの地図プログラムである。 4つのリスナーをインプリメントしているが、そのうち三つがマウス関連である。
マウスのボタン操作関連が MouseListner、マウスポインタの移動に関わるものが MouseMotionListener、 マウスホイールの回転に関するものが MouseWheelListner である。
ComponentListner は画面サイズの変化をキャッチするものであるが、マウス操作でサイズを変えることがあるため、 間接的にはマウス操作が関係している。
地図システムの場合、マウス操作のフル機能を使うわけではないが、上記4つのそれぞれ一部の機能を使う。 使わない場合もイベントハンドラーの記述が必要である。
地図システムの場合、マウスホイールの回転でズームイン・ズームアウトをコントロールしている。 マウスボタンの押し下げで、スクロールの開始、押した状態で、マウスポインタを移動したとき、 その移動に合わせて、地図の中心を変えるスクロールとする。
マウスボタンを押したまま移動したときは mouseMovedイベントでなく mouseDraggedイベントとなる。
class MapCanvas extends JPanel implements
MouseListener, MouseMotionListener, MouseWheelListener, ComponentListener {
int PX=256;
int W=0, H=0; // 地図表示領域の幅,高さ(単位:画素)
Tile.Source src; // gsi, ort, osm, japan, kanto, hot
int zoom=15;
int CX=29081*256, CY=12920*256; // 地図中心タイル座標(単位:画素)
int tx() { return CX/PX; } // 地図中心タイルX座標
int ty() { return CY/PX; } // 地図中心タイルY座標
int MarkX, MarkY;
boolean fCenter = false;
boolean fCenterLine = false;
boolean fTileBoundary = false;
boolean fJapanBoundary = false;
public MapCanvas() {
super();
addMouseListener(this); //マウス入力の有効化
addMouseMotionListener(this);
addMouseWheelListener(this);
addComponentListener(this);
}
void GoTo(double lon, double lat) {
CX = (int) (Lon2X(lon, zoom) * PX);
CY = (int) (Lat2Y(lat, zoom) * PX);
repaint();
}
void ZoomUp(int n) {
if (zoom + n >= 2 && zoom + n <= ( (
src==Tile.Source.japan || src==Tile.Source.kanto || src==Tile.Source.hot) ?
21 : (src==Tile.Source.osm || src==Tile.Source.plateau) ? 19 : 18) ) {
zoom += n;
if (n == 1) { CX *= 2; CY *= 2; }
else { CX /= 2; CY /= 2; }
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString(zoom + "/" + tx() + "/" + ty(), 5, H-8);
g.drawString("(C)OpenStreetMap協力者", W-150, H-10);
if (fCenterLine) {
g.drawLine(0, H/2, W, H/2);
g.drawLine(W/2, 0, W/2, H);
}
if (fCenter) {
Graphics2D g2 = (Graphics2D)g;
g2.setStroke(new BasicStroke(3)); // 太さ3
g.setColor(new Color(255,0,0));
g.drawLine(W/2-5, H/2, W/2+5, H/2);
g.drawLine(W/2, H/2-5, W/2, H/2+5);
}
if (fTileBoundary) {
int nxBGN = (int) ((CX - W/2.0)/PX) - 1;
int nxEND = (int) ((CX + W/2.0)/PX) + 1;
for (int nx = nxBGN; nx <= nxEND; nx++) {
int nxBgn = (int) (nx * PX - (CX - W / 2.0));
g.drawLine(nxBgn, 0, nxBgn, H);
}
int nyBGN = (int) ((CY - H / 2.0) / PX) - 1;
int nyEND = (int) ((CY + H / 2.0) / PX) + 1;
for (int ny = nyBGN; ny <= nyEND; ny++) {
int nyBgn = (int) (ny * PX - (CY - H / 2.0));
g.drawLine(0, nyBgn, W, nyBgn);
}
}
}
@Override
public void mouseClicked(MouseEvent e) { // マウスのボタンがクリックされた
}
@Override
public void mousePressed(MouseEvent e) { // マウスのボタンが押し下げられた
MarkX = e.getX();
MarkY = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) { // マウスのボタンが離された
MarkX = MarkY = -1;
}
@Override
public void mouseEntered(MouseEvent e) {// 画面内にマウスカーソルが侵入した
}
@Override
public void mouseExited(MouseEvent e) { // マウスカーソルが画面外へ出た
}
@Override
public void mouseDragged(MouseEvent e) { //ドラッグしたとき
int eX = e.getX();
int eY = e.getY();
CX -= eX - MarkX;
CY -= eY - MarkY;
MarkX = eX;
MarkY = eY;
repaint();
}
@Override
public void mouseMoved(MouseEvent e) { //移動したとき
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) { // マウスホイールが回された時
if ( e.getWheelRotation() == -1 ) { // 奥に回した
ZoomUp(1);
} else if (e.getWheelRotation() == 1) { // 手前に回した
ZoomUp(-1);
}
repaint();
}
// サイズの変更
@Override
public void componentHidden(ComponentEvent e) { }
@Override
public void componentMoved(ComponentEvent e) { }
@Override
public void componentResized(ComponentEvent e) {
W = getWidth();
H = getHeight();
repaint();
}
@Override
public void componentShown(ComponentEvent e) { }
}