• category: swing folder: KnockoutTextLabel title: JLabelのテキストで背景画像を切り抜いて表示する tags: [JLabel, Font, Graphics, Area] author: aterai pubdate: 2020-12-14T02:32:02+09:00 description: JLabelに描画した背景画像をテキストの図形で切り抜いたように表示します。 image: https://drive.google.com/uc?id=1KAsr3O8es4_eQzJc8N4DLBs9vIB-eJMx

概要

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

サンプルコード

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 in GitHub: Java, Kotlin

解説

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

参考リンク

コメント