首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用JLayer绘制边框装饰滚动工具栏按钮

用JLayer绘制边框装饰滚动工具栏按钮
EN

Stack Overflow用户
提问于 2016-05-18 09:12:23
回答 1查看 831关注 0票数 3

我试图用一个JButton包装一个JLayer,以便向它添加一些效果/功能。当我用工具栏中的包装器替换按钮时,它会出于某种原因绘制按钮边框。工具栏的滚动设置为true

为什么会发生这种情况,我怎样才能防止它发生?

代码语言:javascript
复制
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayer;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.LayerUI;

public class JLayerButton extends JFrame {

    private JToolBar toolbar;
    private JButton button1;
    private JButton button2;
    private JButton button3;

    public JLayerButton() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setTitle("JLayer Button");
        setLayout(new BorderLayout());

        toolbar = new JToolBar();
        toolbar.setFloatable(false);
        toolbar.setRollover(true);
        getContentPane().add(toolbar, BorderLayout.NORTH);

        button1 = new JButton("One");
        button1.setFocusable(false);
        toolbar.add(button1);
        button2 = new JButton("Two");
        button2.setFocusable(false);
        toolbar.add(button2);
        button3 = new JButton("Three");
        button3.setFocusable(false);
        toolbar.add(button3);

        // wrap button2 in JLayer
        int componentIndex = toolbar.getComponentIndex(button2);
        JButtonLayerUI layerUI = new JButtonLayerUI();
        JLayer<JButton> layer = new JLayer<JButton>(button2, layerUI);
        layer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
        layer.setFocusable(false);
        toolbar.add(layer, componentIndex);

        setSize(300, 200);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) 
            throws ClassNotFoundException, InstantiationException, 
            IllegalAccessException, UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JLayerButton().setVisible(true);
            }
        });
    }

    private static class JButtonLayerUI extends LayerUI<JButton> {

        public JButtonLayerUI() {
        }

        @Override
        public void paint(Graphics g, JComponent c) {
            super.paint(g, c);
        }

        @Override
        protected void processMouseEvent(MouseEvent e, JLayer<? extends JButton> l) {
            onMouseEvent(l, e);
        }

        @Override
        protected void processMouseMotionEvent(MouseEvent e, JLayer<? extends JButton> l) {
            onMouseEvent(l, e);
        }

        private void onMouseEvent(JLayer<? extends JButton> l, MouseEvent e) {
            System.out.println(e);
        }        

    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-18 09:46:22

您想要实现的目标在JLayer看来是不可能的,因为:

BasicToolBarUI的代码中,我们可以看到这些调用

调用installRolloverBordersJToolBar上安装边框:

代码语言:javascript
复制
public void setRolloverBorders( boolean rollover ) {
        rolloverBorders = rollover;

        if ( rolloverBorders )  {
            installRolloverBorders( toolBar );
        } else  {
            installNonRolloverBorders( toolBar );
        }
    }

installRolloverBorders在工具栏的每个直接 JComponent子程序(非递归)上调用

代码语言:javascript
复制
protected void installRolloverBorders ( JComponent c )  {
        // Put rollover borders on buttons
        Component[] components = c.getComponents();

        for (Component component : components) {
            if (component instanceof JComponent) {
                ((JComponent) component).updateUI();
                setBorderToRollover(component);
            }
        }
    }

最后,setBorderToRollover只在AbstractButton的实例上工作,而JLayer不是。因此,您的JLayer按钮的原始边框完全不受影响。

代码语言:javascript
复制
protected void setBorderToRollover(Component c) {
        if (c instanceof AbstractButton) {
            AbstractButton b = (AbstractButton)c;

            Border border = borderTable.get(b);
            if (border == null || border instanceof UIResource) {
                borderTable.put(b, b.getBorder());
            }

            // Only set the border if its the default border
            if (b.getBorder() instanceof UIResource) {
                b.setBorder(getRolloverBorder(b));
            }

            rolloverTable.put(b, b.isRolloverEnabled()?
                              Boolean.TRUE: Boolean.FALSE);
            b.setRolloverEnabled(true);
        }
    }

总之,滚转效应只适用于满足上述两种条件的组件:

  1. 是直接的JToolBar子级
  2. AbstractButton的一个实例

您可能会提交您自己版本的BasicToolBarUI,并覆盖一些方法来添加递归,例如,看看是否值得花时间。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37295099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档