Reputation: 115
I have a multi-layered java application that has a range of JLabel buttons that require the hand cursor such as:
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
However, I have a layer above that has bounds covering the entire application (for drawing pop-ups and such). Now that I have added the layer above, my cursor doesn't change anymore. I have tried setting the cursor to null for the layer above, but it has no affect.
Here is the basic layout of the layers:
private void create() {
this.addWindowListener(windowAdapter);
this.setLayout(new BorderLayout());
layers = new JLayeredPane();
layers.setPreferredSize(this.getSize());
dashboard = new DashBoard.DashBoardLayer();
dashboard.setBounds(0, this.getHeight()-275, this.getWidth(),275);
application = new App.ApplicationLayer();
application.setBounds(0,0,this.getWidth(),this.getHeight()-145);
filter = new FilterLayer();
filter.setBounds(0,195,this.getWidth(),490);
menuBG = MenuLayerBg.getInstance();
menuBG.setBounds(0,0,this.getWidth(),this.getHeight());
menuPanes = MenuLayer.getInstance();
menuPanes.setBounds(0,0,this.getWidth(),this.getHeight());
layers.add(application, new Integer(0));
layers.add(filter, new Integer(1));
layers.add(dashboard, new Integer(2));
layers.add(menuBG, new Integer(3));
layers.add(menuPanes, new Integer(4));
this.add(layers, BorderLayout.CENTER);
}
Upvotes: 0
Views: 263
Reputation: 324207
The MouseEvent is only dispatched to the component on the top. So if your top layers completely cover the components on the bottom layers, they will not receive the MouseEvent.
Take a look at the LayeredPaneDemo.java
code found in the Swing tutorial on How to Use Layered Panes. I made the following change to the code:
for (int i = 0; i < layerStrings.length; i++) {
JLabel label = createColoredLabel(layerStrings[i],
layerColors[i], origin);
layeredPane.add(label, new Integer(i));
origin.x += offset;
origin.y += offset;
label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // added
}
Each component is of a fixed smaller size than the entire frame so events will be accepted by components below the top components.
When you run the code the cursor will change on the top two labels.
If you change "Dukes Layer and Position" to be "Yellow" and uncheck the check box, then the cursor will change for all labels.
However, I have a layer above that has bounds covering the entire application
One possible solution is to "redispatch the mouse events" to the components below the top layer. For an example of this approach check out the GlassPaneDemo.java
from the Swing tutorial on How to Use Root Panes
Or for a completely different approach you can try overriding the contains(...)
method of your components to always return false. This way the mouse event will never be dispatched to your component since the mouse point does not belong to the component. I have never tried this before so I don't know if this will cause other problems.
I tried this in the LayeredPaneDemo by making the following changed to the createColoredLabel(...)
method:
JLabel label = null;
if (color.equals(Color.green))
{
label = new JLabel(text)
{
@Override
public boolean contains(int x, int y)
{
return false;
}
};
}
else
label = new JLabel(text);
//JLabel label = new JLabel(text);
Upvotes: 1