概要

JLabelに描画した背景画像をテキストの図形で切り抜いたように表示します。

スクリーンショット

Swing/KnockoutTextLabel.png

サンプルコード

JLabel label = new JLabel("ABC") {
  @Override protected void paintComponent(Graphics g) {
    // super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.drawImage(image, 0, 0, getWidth(), getHeight(), this);
    FontRenderContext frc = g2.getFontRenderContext();
    String text = getText();
    GlyphVector gv = getFont().createGlyphVector(frc, text);
    Rectangle2D b = gv.getVisualBounds();
    double w = getWidth();
    double h = getHeight();
    double cx = w / 2d - b.getCenterX();
    double cy = h / 2d - b.getCenterY();
    AffineTransform toCenterAtf = AffineTransform.getTranslateInstance(cx, cy);
    Shape s = toCenterAtf.createTransformedShape(gv.getOutline());
    Area bg = new Area(new Rectangle2D.Double(0d, 0d, w, h));
    bg.subtract(new Area(s));
    g2.setColor(getBackground());
    g2.fill(bg);
    g2.dispose();
  }
};
label.setBackground(new Color(0xE6_00_00_32, true));
label.setFont(new Font(Font.SERIF, Font.BOLD, 140));
view all

解説

  • JLabel#paintComponent(...)をオーバーライドして背景画像を描画
  • Font#createGlyphVector(frc, "ABC")GlyphVectorを生成
  • GlyphVector#getOutline()でテキストの図形(Shape)を取得
  • JLabelの矩形からテキストの図形を切り抜いた図形をArea#subtract(...)で生成して背景色で塗り潰す
    • 背景色はhasAlphaにチェックがある場合は半透明に設定

参考リンク

コメント