Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 531
nokul Avatar asked Sep 10 '12 07:09

nokul


1 Answers

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);
}
like image 168
chenyi1976 Avatar answered Sep 18 '22 01:09

chenyi1976