按钮角不会被边框覆盖,而是向外移动

问题描述 投票:0回答:1

我正在尝试制作一个自定义按钮(扩展

BasicButtonUI
),具有圆角。我发现我应该使用覆盖按钮方角的圆形边框。 我正在为我的按钮添加边框,如下所示:

b.setBorder(new RoundedBorder(20));

我是这样画边框的:

public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Constants.windowColor);
    g2d.setStroke(new BasicStroke(5f)); // Width of 5 pixels.
    g2d.setPaintMode();
    g2d.drawRoundRect(x, y, width-1, height-1, radius, radius);
}

但是,正如您在下面的屏幕截图中看到的那样,按钮的角向外“移动”了。它们甚至不与按钮的边缘对齐!

放大后是这样的:

截图上看起来不太像,但在现实生活中看起来很奇特!

java swing border jbutton
1个回答
0
投票

我很困惑,为什么不修改您的自定义

BasicButtonUI
以绘制圆角区域,例如使用
RoundRectangle2D
之类的东西。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.basic.BasicButtonUI;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            setBackground(Color.RED);
            setBorder(new EmptyBorder(23, 32, 32, 32));

            JButton circleButton = new JButton("Hello");
            circleButton.setUI(new CircleButtonUI());
            circleButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("I've been triggered");
                }
            });

            add(circleButton);
        }
    }

    public class CircleButtonUI extends BasicButtonUI {

        private Shape buttonShape;

        @Override
        public void installUI(JComponent c) {
            super.installUI(c);
            c.setOpaque(false);
            // This is because on some platforms, the background
            // is undefined or otherwise causes the button not
            // to render
            c.setBackground(Color.LIGHT_GRAY.brighter());
        }

        @Override
        public boolean contains(JComponent c, int x, int y) {
            if (buttonShape == null) {
                return c.contains(x, y);
            }
            return buttonShape.contains(x, y);
        }

        @Override
        public void paint(Graphics g, JComponent c) {
            int width = c.getWidth() - 2;
            int height = c.getHeight() - 2;
            buttonShape = new RoundRectangle2D.Double(1, 1, width, height, 20, 20);
            AbstractButton b = (AbstractButton) c;
            paintContent(g, b);
            super.paint(g, c);
        }

        protected void paintContent(Graphics g, AbstractButton b) {
            if (buttonShape == null) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            // paint the interior of the button
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            ButtonModel model = b.getModel();
            Color highlight = b.getBackground();
            if (model.isArmed() && model.isPressed()) {
                highlight = highlight.darker();
            }
            Color darklight = highlight.darker();

            LinearGradientPaint lgp = new LinearGradientPaint(
                    buttonShape.getBounds().getLocation(),
                    new Point((int) buttonShape.getBounds().getMaxX(), (int) buttonShape.getBounds().getMaxY()),
                    new float[]{0, 1f},
                    new Color[]{highlight, darklight});

            g2d.setPaint(lgp);
            g2d.fill(buttonShape);

            // draw the perimeter of the button
            g2d.setColor(b.getBackground().darker().darker().darker());
            g2d.draw(buttonShape);
            g2d.dispose();
        }

        @Override
        protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
            // Paint focus highlight, if you want to
        }

        public Dimension getMinimumSize(JComponent c) {
            Dimension size = super.getMinimumSize(c);
            return new Dimension(size.width + 8, size.height + 16);
        }

        public Dimension getPreferredSize(JComponent c) {
            Dimension size = super.getPreferredSize(c);
            return new Dimension(size.width + 8, size.height + 16);
        }

        public Dimension getMaximumSize(JComponent c) {
            Dimension size = super.getPreferredSize(c);
            return new Dimension(size.width + 8, size.height + 16);
        }
    }
}

请注意,这只是一个示例,您需要做更多的工作才能获得功能齐全的实现。

© www.soinside.com 2019 - 2024. All rights reserved.