你能让JToolBar不可移动吗?

时间:2015-05-27 14:00:31

标签: java swing jtoolbar

我想让我的JToolBar无法从其容器中分离,但仍然允许用户将其拖到容器的一侧。

我知道

public void setFloatable( boolean b )

但这根本不允许用户移动JToolBar。

有没有办法在不覆盖ToolBarUI的情况下这样做?

此外,是否可以选择在放弃之前突出显示新位置?

2 个答案:

答案 0 :(得分:2)

  • 在WinOS上非常正确地为我工作,来自SunForum的旧代码

enter image description here

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class CaptiveToolBar {

    private Robot robot;
    private JDialog dialog;
    private JFrame frame;

    public static void main(String[] args) {
        //JFrame.setDefaultLookAndFeelDecorated(true);
        //JDialog.setDefaultLookAndFeelDecorated(true);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new CaptiveToolBar().makeUI();
            }
        });
    }

    public void makeUI() {
        try {
            robot = new Robot();
        } catch (AWTException ex) {
            ex.printStackTrace();
        }
        final JToolBar toolBar = new JToolBar();
        for (int i = 0; i < 3; i++) {
            toolBar.add(new JButton("" + i));
        }
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.add(toolBar, BorderLayout.NORTH);

        final ComponentListener dialogListener = new ComponentAdapter() {

            @Override
            public void componentMoved(ComponentEvent e) {
                dialog = (JDialog) e.getSource();
                setLocations(false);
            }
        };
        toolBar.addHierarchyListener(new HierarchyListener() {

            @Override
            public void hierarchyChanged(HierarchyEvent e) {
                Window window = SwingUtilities.getWindowAncestor(toolBar);
                if (window instanceof JDialog) {
                    boolean listenerAdded = false;
                    for (ComponentListener listener : window.getComponentListeners()) {
                        if (listener == dialogListener) {
                            listenerAdded = true;
                            break;
                        }
                    }
                    if (!listenerAdded) {
                        window.addComponentListener(dialogListener);
                    }
                }
            }
        });
        frame.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentMoved(ComponentEvent e) {
                if (dialog != null && dialog.isShowing()) {
                    setLocations(true);
                }
            }
        });
        frame.setVisible(true);
    }

    private void setLocations(boolean moveDialog) {
        int dialogX = dialog.getX();
        int dialogY = dialog.getY();
        int dialogW = dialog.getWidth();
        int dialogH = dialog.getHeight();
        int frameX = frame.getX();
        int frameY = frame.getY();
        int frameW = frame.getWidth();
        int frameH = frame.getHeight();
        boolean needToMove = false;
        if (dialogX < frameX) {
            dialogX = frameX;
            needToMove = true;
        }
        if (dialogY < frameY) {
            dialogY = frameY;
            needToMove = true;
        }
        if (dialogX + dialogW > frameX + frameW) {
            dialogX = frameX + frameW - dialogW;
            needToMove = true;
        }
        if (dialogY + dialogH > frameY + frameH) {
            dialogY = frameY + frameH - dialogH;
            needToMove = true;
        }
        if (needToMove) {
            if (!moveDialog && robot != null) {
                robot.mouseRelease(InputEvent.BUTTON1_MASK);
            }
            dialog.setLocation(dialogX, dialogY);
        }
    }
}

答案 1 :(得分:2)

这不是最优雅的解决方案,但它确实有效。

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();
    }
}

说明:

每当工具栏移动到浮动状态时,都会指示不这样做。唯一的问题是你必须等待EDT完成创建浮动窗口的过程,然后才能告诉它不要浮动。结果是您实际看到窗口已创建然后隐藏。

注意:

我认为覆盖工具栏的UI是一个更好的解决方案,尽管使用更复杂的方法做一些类似于我所做的事情也可能效果很好。