Rounded LineBorder - 并非所有角都是圆角

我正在使用JFreeChart并且我想ToolTip通过创建我自己的Class扩展ChartPanel和覆盖来自定义createToolTip()。


static private class PrivateChartPanel extends ChartPanel{


    //constructors


    @Override

    public JToolTip createToolTip() {


        JToolTip jtt = super.createToolTip();


        jtt.setBackground(Color.WHITE);


        jtt.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));


        return jtt;


    }


}

问题出在Border。它不是在所有角落都是圆形的。

http://img4.mukewang.com/618cd82f0001a6a101140107.jpg

为什么它不是在所有角落都圆润的,我是怎么做到的?


PS:我新建了一个简单的项目


import java.awt.Color;


import javax.swing.BorderFactory;

import javax.swing.JFrame;

import javax.swing.JPanel;


public class HelloWorld {


  public static void main(String[] args) {


    JFrame a = new JFrame();


    a.setBounds(100, 100, 100, 100);

    a.setLayout(null);


    JPanel b = new JPanel();


    b.setBounds(5, 5, 50, 50);

    b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));


    a.add(b);


    a.setVisible(true);


  }


}

和 JPanel 的边框也有同样的问题。我正在使用Java 10


慕桂英3389331
浏览 182回答 1
1回答

慕桂英4014372

圆角的效果取决于这些圆角的大小。在的情况下LineBorder,由thickness属性决定。这是相关实现代码的样子:int offs = this.thickness;int size = offs + offs;if (this.roundedCorners) {    float arc = .2f * offs;    outer = new RoundRectangle2D.Float(x, y, width, height, offs, offs);    inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc);}else {    outer = new Rectangle2D.Float(x, y, width, height);    inner = new Rectangle2D.Float(x + offs, y + offs, width - size, height - size);}Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);path.append(outer, false);path.append(inner, false);g2d.fill(path);所以它区分了内角和外角,这对于线大小为1的意义不大。但更糟糕的是,外角大小只是offs,与thickness(在您的情况下为一个)相同,而内圆角的大小由 决定arc,即.2f * offs。对于您中thickness的一个,生成的内角大小为0.2。因此,我们在左上角看到效果似乎纯属巧合(这两个不同角的圆角问题),因为即使一个较大的外角尺寸也不足以创建可见的圆角效果。下面是 a thicknessof 的样子20,这会导致外角大小为 ,20而内角大小为4:它不知道 Swing 开发人员在该类中添加圆角支持时考虑的是哪个实际用例。我无法想象这种策略有用的任何场景。实现一个有意义Border的并不难。一种可能的实现如下所示:public class RoundedLineBorder extends AbstractBorder {    int lineSize, cornerSize;    Paint fill;    Stroke stroke;    private Object aaHint;    public RoundedLineBorder(Paint fill, int lineSize, int cornerSize) {        this.fill = fill;        this.lineSize = lineSize;        this.cornerSize = cornerSize;        stroke = new BasicStroke(lineSize);    }    public RoundedLineBorder(Paint fill, int lineSize, int cornerSize, boolean antiAlias) {        this.fill = fill;        this.lineSize = lineSize;        this.cornerSize = cornerSize;        stroke = new BasicStroke(lineSize);        aaHint = antiAlias? RenderingHints.VALUE_ANTIALIAS_ON: RenderingHints.VALUE_ANTIALIAS_OFF;    }    @Override    public Insets getBorderInsets(Component c, Insets insets) {        int size = Math.max(lineSize, cornerSize);        if(insets == null) insets = new Insets(size, size, size, size);        else insets.left = insets.top = insets.right = insets.bottom = size;        return insets;    }    @Override    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {        Graphics2D g2d = (Graphics2D)g;        Paint oldPaint = g2d.getPaint();        Stroke oldStroke = g2d.getStroke();        Object oldAA = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);        try {            g2d.setPaint(fill!=null? fill: c.getForeground());            g2d.setStroke(stroke);            if(aaHint != null) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);            int off = lineSize >> 1;            g2d.drawRoundRect(x+off, y+off, width-lineSize, height-lineSize, cornerSize, cornerSize);        }        finally {            g2d.setPaint(oldPaint);            g2d.setStroke(oldStroke);            if(aaHint != null) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAA);        }    }}现在,当我改变线路时b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));在你的例子中b.setBorder(new RoundedLineBorder(Color.BLACK, 1, 10, true));我得到
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java