JPanel 一侧的虚线边框

Dashed border from one side for JPanel

有没有一种方法可以仅从一侧向 Java Swing 组件(如 JPanelJLabel 添加 虚线 边框?

该问题与 another question 不重复,因为该问题涉及一侧的线条边框。但是我需要虚线边框。

The question is not duplicate of another question because that question refers to a line border for one side

是的,它是重复的,因为 API 向您展示了如何在单侧使用 MatteBorderIcon。所以你需要做的就是创建一个 "Dashed Line Icon"。请参阅下面我的代码中发布的示例。

或者帖子中未列出的第二个选项是使用 CompoundBorder 来创建您想要的效果:

Border empty = BorderFactory.createEmptyBorder(0, -1, -1, -1);
Border dashed = BorderFactory.createDashedBorder(null, 5, 5);
Border compound = new CompoundBorder(empty, dashed);

通过将 EmptyBorder 尺寸设置为 -1,您将组合尺寸设置为 0,因此 DashedBorder 仅在一侧绘制。

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

public class DashedBorder extends JPanel
{
    public DashedBorder()
    {
        //  Use an Icon in the MatteBorder

        JLabel label1 = new JLabel("Label Using a Matte Border");
        add(label1);

        Icon icon = new DashedLineIcon(Color.BLACK, 5, 1, 5, 0);
        Border matte = BorderFactory.createMatteBorder(1, 0, 0, 0, icon);
        label1.setBorder( matte );
        System.out.println(matte.getBorderInsets(label1));

        add(Box.createHorizontalStrut(100));
        //  Create a CompoundBorder using the DashedBorder

        JLabel label2 = new JLabel("Label Using a Dashed Border");
        add(label2);

        Border dashed = BorderFactory.createDashedBorder(null, 5, 5);
        Border empty = BorderFactory.createEmptyBorder(1, -1, -1, -1);
        Border compound = new CompoundBorder(empty, dashed);
        label2.setBorder( compound );
        System.out.println(compound.getBorderInsets(label2));

    }

    static public class DashedLineIcon implements Icon
    {
        private Color color;
        private int dashWidth;
        private int dashHeight;
        private int emptyWidth;
        private int emptyHeight;

        public DashedLineIcon(Color color, int dashWidth, int dashHeight, int emptyWidth, int emptyHeight )
        {
            this.color = color;
            this.dashWidth = dashWidth;
            this.dashHeight = dashHeight;
            this.emptyWidth = emptyWidth;
            this.emptyHeight = emptyHeight;
        }

        public int getIconWidth()
        {
            return dashWidth + emptyWidth;
        }

        public int getIconHeight()
        {
            return dashHeight + emptyHeight;
        }

        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            g.setColor(color);
            g.fillRect(x, y, dashWidth, dashHeight);
        }
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("Dashed Border");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new DashedBorder());
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

我也想到了这个解决方案,虽然它有点复杂:

private void drawBorder(Graphics g){
  int x = this.getWidth();
  float dash[] = {1.0f};
  Graphics2D g2;
  BasicStroke stroke;

  g2 = (Graphics2D)g;
  stroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, dash, 0.0f);
  g2.setStroke(stroke);
  g2.setColor((Color) new Color(120, 120, 120));

  g2.draw(new Line2D.Double(0, 0, x, 0));
}

panel = new JPanel(){
  @Override
  public void paintComponent(Graphics g){
    drawBorder(g);
  }
};

在这里,我用 Graphics2D 方法画了顶线,并使用 BasicStroke class 创建了实际上是点的破折号,因为密度数组 dash 告诉它有破折号之间的 space 个 1 作为破折号的长度。