【问题标题】:Change JButton focus area更改 JButton 焦点区域
【发布时间】:2014-06-04 12:11:14
【问题描述】:

如何更改 JButton 上的焦点区域,以便当我将光标悬停在按钮上时,我的服装翻转图标不会在光标位于实际按钮本身之前稍微激活。

【问题讨论】:

    标签: java swing jbutton


    【解决方案1】:

    按钮的contains(x, y) 方法确定鼠标何时进入按钮。如果您的自定义按钮不是矩形,那么您需要重写此方法。

    这是一个演示这个概念的旧示例:

    // Old example code found on the internet somewhere
    // to paint a Round button with hit detection
    
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import javax.swing.*;
    
    public class RoundButton extends JButton
    {
        public RoundButton(String label)
        {
            super(label);
    
            // These statements enlarge the button so that it
            // becomes a circle rather than an oval.
            Dimension size = getPreferredSize();
            size.width = size.height = Math.max(size.width, size.height);
            setPreferredSize(size);
            setSize(size);
    
            // This call causes the JButton not to paint the background.
            // This allows us to paint a round background.
            setContentAreaFilled(false);
        }
    
        // Paint the round background and label.
        protected void paintComponent(Graphics g)
        {
            if (getModel().isArmed()) {
                    // You might want to make the highlight color
                    // a property of the RoundButton class.
                    g.setColor(Color.lightGray);
                } else {
                    g.setColor(getBackground());
                }
            g.fillOval(0, 0, getSize().width-1, getSize().height-1);
    
                // This call will paint the label and the focus rectangle.
            super.paintComponent(g);
        }
    
        // Paint the border of the button using a simple stroke.
        protected void paintBorder(Graphics g)
        {
            g.setColor(getForeground());
            g.drawOval(0, 0, getSize().width-1, getSize().height-1);
        }
    
        // Hit detection.
        Shape shape;
    
        public boolean contains(int x, int y)
        {
            // If the button has changed size, make a new shape object.
            if (shape == null || !shape.getBounds().equals(getBounds())) {
                shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
            }
            return shape.contains(x, y);
        }
    
        private static void createAndShowUI()
        {
            // Create buttons that overlap one another
    
            JButton button = new RoundButton("Jackpot");
            button.setBackground(Color.green);
            button.setLocation(0, 0);
    
            JButton button2 = new RoundButton("Jackpot2");
            button2.setBackground(Color.red);
            button2.setLocation(40, 40);
    
            // Create a frame in which to show the button.
            JFrame frame = new JFrame("Round Button");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().setBackground(Color.yellow);
            frame.setLayout(null);
            frame.add(button);
            frame.add(button2);
            //frame.setLayout(new FlowLayout());
            frame.setLocationByPlatform( true );
            frame.setSize(250, 200);
            frame.setVisible(true);
    
            MouseListener mouseListener = new MouseAdapter()
            {
                public void mouseEntered( MouseEvent e ) {}
    
                public void mouseExited( MouseEvent e ) {}
    
                public void mouseClicked( MouseEvent e )
                {
                    System.out.println( "clicked " );
                }
    
                public void mousePressed( MouseEvent e )
                {
                    System.out.println( "pressed " );
                }
    
                public void mouseReleased( MouseEvent e )
                {
                    System.out.println( "released " );
                }
            };
    
            button.addMouseListener( mouseListener );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }
    

    【讨论】:

    • 首先我很惊讶看到你将代码发布到 SO,然后..button.setBounds(0, 0, 100, 100);.. 你是 真的 camickr,还是只是设法破解该帐户的人?!?
    • 正如我所说,这是旧代码。也许不是使用空布局的最佳示例,但它确实演示了即使通过覆盖 contains(...) 方法将组件堆叠在另一个之上,Swing 组件的命中检测如何工作。
    • 好吧.. 不得不说,我仍然很惊讶您会公开将代码与您的名字相关联,这有点削弱了我的“每一滴 camickr 都是纯金”的理论。不确定是否要动摇我对宇宙的信念,或者只是享受即使大师有时也会走捷径的示范......;)
    • 'every drop of camickr is pure gold' theory - 甚至黄金也不是 100% 纯的 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    相关资源
    最近更新 更多