how to z-order index / z-layer index for redrawing of top down map.

i am trying to modify and existing open source program that emulates a virtual tabletop surface for multiple people on via networking. at current, there are two "layers" to the table: one for map backgrounds, and one for 'objects' on the map-people, buildings, vehicles, etc. i constantly run into problems trying to prevent images on one of the layers from overlapping and blocking off each other visually.

i have not been able to find anything in the api yet, perhaps my keywords are not the right ones. what i need is to find out how to assign a "z-order" index to each instance of an image placed on the virtual tabletop. much like dhtml has a "z-layer" property, i would like this program to redraw the visible images in a specific order, determined by thier "z-order" variable value.

i thought this would be the simplest way to emulate multiple layers within the program. the ultimate goal being sought after here is to have multiple "vertical" layers for holding the objects on the map.

thanks for any help with this. =)

edit: nijineko: clarification

[1092 byte] By [nijinekoa] at [2007-10-3 9:46:21]
# 1

There are two basic approaches that come to mind for what you describe.

1 — Component approach: use a JLayeredPane (or j2se 1.5+ Component z-order) with your images mounted in JLabels. You can set the z–order for these labels. The Swing tutorial has an example of how to do this: [url=http://java.sun.com/docs/books/tutorial/uiswing/components/layeredpane.html]How to Use Layered Panes[/url]

2 — Graphic approach: draw all of the images in the paintComponent method of a JPanel and control the z–layering affect with state/member variables such as an array of indices.

Here's an example of how you could do the second option:

import java.awt.*;

import java.awt.event.*;

import java.awt.image.BufferedImage;

import javax.swing.*;

public class LayeredImages extends JPanel {

BufferedImage[] images;

Rectangle[] rects;

int[] indices;

LayeredImages() {

images = createImages();

indices = new int[images.length];

for(int j = 0; j < indices.length; j++)

indices[j] = j;

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

if(rects == null)

initRects();

for(int j = 0; j < images.length; j++)

g2.drawImage(images[indices[j]], rects[j].x, rects[j].y, this);

}

private void initRects() {

rects = new Rectangle[images.length];

int w = getWidth();

int h = getHeight();

int width = images[0].getWidth();

int height = images[0].getHeight();

for(int j = 1; j < images.length; j++) {

width += images[j].getWidth()/2;

height += images[j].getHeight()/2;

}

Point p0 = new Point();

p0.x = (w - width)/2;

p0.y = (h - height)/2;

int x = p0.x;

int y = p0.y;

for(int j = 0; j < rects.length; j++) {

rects[j] = new Rectangle(x, y, images[j].getWidth(),

images[j].getHeight());

x += images[j].getWidth()/2;

y += images[j].getHeight()/2;

}

}

private BufferedImage[] createImages() {

Color[] colors = { Color.red, Color.green, Color.blue, Color.yellow };

BufferedImage[] images = new BufferedImage[colors.length];

for(int j = 0, s = 75; j < images.length; j++) {

images[j] = new BufferedImage(s, s, BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = images[j].createGraphics();

g2.setPaint(colors[j]);

g2.fillRect(0,0,s,s);

g2.dispose();

}

return images;

}

public static void main(String[] args) {

LayeredImages test = new LayeredImages();

test.addMouseListener(test.selector);

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.getContentPane().add(test);

f.setSize(400,400);

f.setLocation(200,200);

f.setVisible(true);

}

private MouseListener selector = new MouseAdapter() {

public void mousePressed(MouseEvent e) {

Point p = e.getPoint();

// count top-down, from high z-order to low

for(int j = indices.length-1; j >= 0; j--) {

if(rects[j].contains(p)) {

resetIndices(j);

repaint();

break;

}

}

}

private void resetIndices(int selectedIndex) {

// save index of image at selectedIndex in indices array

int topImageIndex = indices[selectedIndex];

// slide all later (than selectedIndex) values down one place

for(int j = selectedIndex; j < indices.length-1; j++)

indices[j] = indices[j+1];

// put topImageIndex in last place (top of z-order);

indices[indices.length-1] = topImageIndex;

}

};

}

crwooda at 2007-7-15 5:03:09 > top of Java-index,Security,Cryptography...
# 2

Please make these changes to the app posted above for proper behavior:

protected void paintComponent(Graphics g) {

...

if(rects == null)

initRects();

for(int j = 0; j < images.length; j++) {

int k = indices[j];

g2.drawImage(images[k], rects[k].x, rects[k].y, this);

}

}

...

private MouseListener selector = new MouseAdapter() {

...

for(int j = indices.length-1; j >= 0; j--) {

if(rects[indices[j]].contains(p)) {

resetIndices(j);

crwooda at 2007-7-15 5:03:09 > top of Java-index,Security,Cryptography...
# 3
thanks for the sample code, i will see what i can do with that and get back to you with some results. =D
nijinekoa at 2007-7-15 5:03:09 > top of Java-index,Security,Cryptography...