File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Swing / AWT / SWT and the fly likes Enabling pass-through events between Layers in JLayeredPane Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Enabling pass-through events between Layers in JLayeredPane" Watch "Enabling pass-through events between Layers in JLayeredPane" New topic

Enabling pass-through events between Layers in JLayeredPane

Zahid Anwar

Joined: Jul 09, 2008
Posts: 1
Hi all,

I am trying to make a simple graph visualization GUI App, that reads nodes/edges info from a file and displays it as circles and lines. The user should be able to drag the circles around for better viewing and save the file (with the updated x,y node coordinates).

I am using JLayeredPane with three layers. The lowest layer 0 is a background image, layer 1 are Nodes which are basically extended from JLabel and finally the top most layer is a JPanel whose paintComponent(Graphics g) function I use to draw lines representing edges between the nodes.

The trouble I am having is that dragging the mouse on the screen will move the top-most layer (the panel with the edges) around instead of the nodes. Moving the JLabel nodes to the top using layeredPane.setlayer(node,2) resolves this problem but then the nodes hide the arrowheads of the edges. Is there a way the edges panel can remain on the top but pass the drag events to the nodes in the layer below? Here is my code, I took out the file processing and node, link classes for simplicity.


---------------code begins-------------------
class myDrawing extends JPanel { //this is the panel that draws the edges
private Hashtable Services;
public myDrawing(Hashtable Services)
this.Services = Services;

private void drawcurvedarrow(Graphics2D g, int x1, int y1, int x2, int y2, int ctr1, int ctr2)
QuadCurve2D q = new QuadCurve2D.Float();
// draw QuadCurve2D.Float with set coordinates
double lengthX = x2 - x1;
double lengthY = y2 - y1;
q.setCurve(x1, y1, ctr1+10, ctr2+10, x2, y2);

// Calulate the length of the line
double lineLength = Math.sqrt (lengthX * lengthX + lengthY * lengthY);
int startAngle;
int angle = 60;
int width = 20;
int height = 20;
startAngle = (int)Math.toDegrees(Math.asin(lengthY/lineLength));
if (lengthX > 0)
startAngle = (180 - startAngle - 30);
startAngle = (startAngle - 30);

// Draw the arrow head
g.fillArc (x2 - (width/2), y2 - (height/2)+1, width, height, startAngle,angle);

protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
BasicStroke thinStroke = new BasicStroke(2.0f);

if(Services != null)
Iterator liter = Services.values().iterator();
while (liter.hasNext ()) {
serviceModel sm = (serviceModel);
devModel dm1 = sm.getDevice();
String[] svcEffected = sm.getServEff();
for(int i=0;i<svcEffected.length;i++)
serviceModel sm1 = (serviceModel) Services.get(svcEffected[i]);
devModel dm2 = sm1.getDevice();

srcX = dm1.getX();
srcY = dm1.getY();

dstX = dm2.getX();
dstY = dm2.getY();

midsrcX = dm1.width /2;
midsrcY = dm1.height /2;

middstX = dm2.width /2;
middstY = dm2.height /2;

int ctr1 = (srcX + dstX)/2;
int ctr2 = (srcY + dstY)/2;


drawcurvedarrow(g2, srcX+midsrcX,srcY+midsrcY,dstX+middstX,dstY+middstY, ctr1, ctr2);



public class Assessment extends JInternalFrame implements MouseListener, MouseMotionListener{
private static final int WIDTH = 900, HEIGHT = 732;
private Hashtable devices = null;
private Hashtable services = null;
private JLayeredPane layeredPane;
private String directory; // the location to the file.
private String name; // the files name.

private JLabel bkgrdLabel=null;
private File location=null;
Component dragComponent = null;
Component moveComponent = null;
int xAdjustment;
int yAdjustment;

public Assessment(String title) {
true, //resizable
true, //closable
true, //maximizable

//Create and set up the layered pane.
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new Dimension(WIDTH, HEIGHT));
layeredPane.setBorder(BorderFactory.createTitledBorder("Visualize Graph"));
layeredPane.setLayout( null );
layeredPane.addMouseListener( this );
layeredPane.addMouseMotionListener( this );

bkgrdLabel = new JLabel();
Image img = new ImageIcon("./pic/"+"scadabkground"+".jpg").getImage();
Image img1 = img.getScaledInstance(WIDTH,HEIGHT,Image.SCALE_SMOOTH);
ImageIcon img2 = new ImageIcon(img);
bkgrdLabel.setBounds(0, 0, WIDTH, HEIGHT);

public void getServices()
//reads edges from a file
public void getDevicesList()
//reads nodes from a file

public void populate()


Iterator it = devices.values().iterator();
devModel device = (devModel);
int curX= device.getX();
int curY= device.getY();
device.setBounds(curX, curY, device.getWidth(), device.getHeight());
layeredPane.setLayer(device, 2);

layeredPane.setLayer(bkgrdLabel, 0);

myDrawing drawing = new myDrawing(links,services);
drawing.setBounds(0, 0, WIDTH, HEIGHT);
layeredPane.setLayer(drawing, 1);


public void drawFrame(JFrame parent) throws Exception

//...Set location and size...

public static void main(String[] args){
ScadaModel sm= new ScadaModel();

** Move the component around the panel
public void mouseDragged(MouseEvent me)
if (dragComponent == null) return;
dragComponent.setLocation(me.getX() + xAdjustment, me.getY() + yAdjustment);



** Deselect the component
public void mouseReleased(MouseEvent e)
dragComponent = null;

public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}

Campbell Ritchie

Joined: Oct 13, 2005
Posts: 46360
Welcome to JavaRanch

I am afraid you will have to go back to your original post, click the pencil-and-paper icon and edit it. Highlight the code, then click the code button underneath the message window. Explain where you get the ServiceModel class from. Otherwise nobody will be able to read your code to help, sorry.
I agree. Here's the link:
subject: Enabling pass-through events between Layers in JLayeredPane
It's not a secret anymore!