javaswingpointersmouseglasspane

Swing: GlassPane prevents mouse pointer from changing


I have a JTabbedPane with some tabs and a lot of unused extra space next to the tabs. So I'm trying to use it and place some buttons there (like in Eclipse). I put the buttons on a GlassPane:

        JPanel glasspane = getPanelWithButtons();
        // panel with FlowLayout.RIGHT
        frame.setGlassPane(glasspane);
        glasspane.setOpaque(false);
        glasspane.setVisible(true);

This works, and I still can click through on the other elements of my gui (most search results I found are about how to prevent this). The only problem so far is that the mouse pointer doesn't change to that double-ended horizontal arrow when it hovers over the bar of a JSplitPane. How can I get this behaviour back?

EDIT

I found that no mouse changing events from any component under the glass pane are shown. Those components would change the mouse cursor to a hand cursor, zoom lenses and others. None of these mouse pointer changes have an effect any more. I guess this is because with the glass pane, the mouse pointer change needs to be made to the glass pane, but I don't want to do all the mouse pointer changing manually.


Solution

  • Well. I figure out how to do it.

    Although I spend more than 5 hours to understand all things behind, but the solution is very simple.

    Just overwrite 'public boolean contains(int x, int y)' method of glass panel.

    public static void main(String[] args)
    {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setSize(800, 600);
    
        final JSplitPane panel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JPanel(), new JPanel());
    
        frame.getContentPane().add(panel, BorderLayout.CENTER);
    
        final JPanel glassPane = new JPanel(){
            @Override
            public boolean contains(int x, int y)
            {
                Component[] components = getComponents();
                for(int i = 0; i < components.length; i++)
                {
                    Component component = components[i];
                    Point containerPoint = SwingUtilities.convertPoint(
                        this,
                        x, y,
                        component);
                    if(component.contains(containerPoint))
                    {
                        return true;
                    }
                }
                return false;
            }
        };
        glassPane.setOpaque(false);
        JButton button = new JButton("haha");
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("haha");
            }
        });
        glassPane.add(button);
        glassPane.setBorder(BorderFactory.createLineBorder(Color.red));
        frame.setGlassPane(glassPane);
    
        //try to comment out this line to see the difference.
        glassPane.setVisible(true);
    
        frame.setVisible(true);
    }