I have a JFrame and a JPanel hierarchy inside it, i want to implement an inner panel that i can make it look "disabled"(while other panels dont change), that is, to cover it by a semi transparent gray layer and intercept all mouse and perhaps even keyboard events that are dispatched to this panel. ive been searching for a solution and didnt really find a good one yet.
The closest i got to a solution was when i used JRootPane, whenever i want it disabled i make its glasspane visible. the glasspane had been set to be opaque and with semi transparent background.
A simple example of my attempt :
public class Test extends JFrame {
private final JPanel jPanel;
public Test() {
jPanel = new JPanel();
final JButton jButton = new JButton("Hidden");
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("hidden is clicked!");
}
});
final JRootPane jRootPane = new JRootPane();
jPanel.add(jRootPane);
final JPanel glassPane = new JPanel();
final JButton jButton2 = new JButton();
jButton2.addActionListener(new ActionListener() {
private boolean visible = true;
@Override
public void actionPerformed(ActionEvent e) {
glassPane.setVisible(visible = !visible);
}
});
jPanel.add(jButton2);
jRootPane.getContentPane().add(new JScrollPane(jButton));
glassPane.setBackground(new Color(0.5f, 0.5f, 0.5f, 0.2f));
glassPane.setOpaque(true);
jRootPane.setGlassPane(glassPane);
glassPane.setVisible(true);
getContentPane().add(jPanel);
}
public static void main(String[] strings) {
final Test test = new Test();
test.pack();
test.setVisible(true);
}
}
But the problem is that even when the glass is visible on top of the content, it doesnt intercepts events from getting to the content as it should, as documented here.
In your test class your glasspane doesn't intercept events, because you didn't tell it to intercept events (intercepting events is not a default behavior).
In the documentation link, it says
The glass pane
The glass pane is useful when you want to be able to catch events or paint over an area that already contains one or more components. For example, you can deactivate mouse events for a multi-component region by having the glass pane intercept the events. Or you can display an image over multiple components using the glass pane.
You can intercept Mouse Events this way:
glassPane.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
e.consume();
}
@Override
public void mousePressed(MouseEvent e)
{
e.consume();
}
});
You can intercept KeyBoard Events this way:
glassPane.setFocusable(true);
glassPane.addKeyListener(new KeyListener()
{
@Override
public void keyTyped(KeyEvent e)
{
e.consume();
}
@Override
public void keyReleased(KeyEvent e)
{
e.consume();
}
@Override
public void keyPressed(KeyEvent e)
{
e.consume();
}
});
Note: The JPanel has to be focasable to intercept the keyboard events.