javaswingjtoolbar

Can you make a JToolBar undetachable?


I would like to make my JToolBar impossible to detach from its container but still let the user drag it to one of the container's sides.

I know about

public void setFloatable( boolean b )

but this won't allow the user to move the JToolBar at all.

Is there any way of doing this without overwriting ToolBarUI?

Also, is there an option to highlight its new position before dropping it?


Solution

  • It's not the most elegant solution, but it works.

    public class Example extends JFrame {
    
        BasicToolBarUI ui;
    
        Example() {
    
            JToolBar tb = new JToolBar();
            tb.add(new JButton("AAAAA"));
            tb.setBackground(Color.GREEN);
            ui = (BasicToolBarUI) tb.getUI();
    
            getContentPane().addContainerListener(new Listener());
            getContentPane().add(tb, BorderLayout.PAGE_START);
    
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setSize(300, 300);
            setLocationRelativeTo(null);
            setVisible(true);
        }
    
        class Listener implements ContainerListener {
    
            @Override
            public void componentAdded(ContainerEvent e) {}
    
            @Override
            public void componentRemoved(ContainerEvent e) {
    
                if (ui.isFloating()) {
                    SwingUtilities.invokeLater(new Runnable() {
    
                        @Override
                        public void run() {
    
                            ui.setFloating(false, null);
                        }
                    }); 
                }
            }
        }
    
        public static void main(String[] args) {
    
            new Example();
        }
    }
    

    Explanation:

    Whenever the toolbar is moving to a floating state, it is instructed not do so. The only problem is that you have to wait for the EDT to finish the process for creating the floating window, and only then can you tell it not to float. The result is that you actually see the window created and then hidden.

    Note:

    I think that overriding the UI for the toolbar is a better solution, though it's possible that with a more intricate approach doing something similar to what I did will also work well.