Swing/FiveStarRatingLabel の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/FiveStarRatingLabel へ行く。
- Swing/FiveStarRatingLabel の差分を削除
--- category: swing folder: FiveStarRatingLabel title: GlyphVectorで作成した5段階評価の結果をラベルに描画する tags: [GlyphVector, Font, JLabel] author: aterai pubdate: 2022-05-16T02:25:26+09:00 description: GlyphVectorを使用して5段階評価の★のアウトラインを作成し、その内部を評価値の小数点一位まで塗りつぶします。 image: https://drive.google.com/uc?id=1qWNar6LNSc0eR0JQQL9exGtmmmNfL-ki --- * 概要 [#summary] GlyphVectorを使用して5段階評価の★のアウトラインを作成し、その内部を評価値の小数点一位まで塗りつぶします。 `GlyphVector`を使用して`5`段階評価の★のアウトラインを作成し、その内部を評価値の小数点一位まで塗りつぶします。 #download(https://drive.google.com/uc?id=1qWNar6LNSc0eR0JQQL9exGtmmmNfL-ki) * サンプルコード [#sourcecode] #code(link){{ // JComponent label1 = new FiveStarRatingLabel("3.5"); class FiveStarRatingLabel extends JComponent { private static final String STAR = "★★★★★"; private final int ip; private final int fp; protected FiveStarRatingLabel(String rating) { super(); BigDecimal bd = new BigDecimal(rating); ip = bd.intValue(); fp = bd.subtract(new BigDecimal(ip)).multiply(BigDecimal.TEN).intValue(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); int w = getWidth(); int h = getHeight(); g.setColor(Color.WHITE); g.fillRect(0, 0, w, h); Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); FontRenderContext frc = g2.getFontRenderContext(); GlyphVector gv = getFont().createGlyphVector(frc, STAR); Rectangle2D r = gv.getVisualBounds(); double cx = w / 2d - r.getCenterX(); double cy = h / 2d - r.getCenterY(); AffineTransform toCenterAtf = AffineTransform.getTranslateInstance(cx, cy); double point = 0d; for (int i = 0; i < gv.getNumGlyphs(); i++) { GlyphMetrics gm = gv.getGlyphMetrics(i); if (i <= ip - 1) { point += gm.getAdvance(); } else if (i <= ip) { point += gm.getBounds2D().getWidth() * fp / 10d; } } g2.setPaint(Color.GREEN); Shape s = toCenterAtf.createTransformedShape(gv.getOutline()); g2.draw(s); Rectangle2D clip = new Rectangle2D.Double(r.getX(), r.getY(), point, r.getHeight()); g2.setClip(toCenterAtf.createTransformedShape(clip)); g2.fill(s); g2.dispose(); } } }} * 解説 [#explanation] - `5`段階評価用に★を`5`文字分用意 - `Font#createGlyphVector(...)`でその文字列★★★★★から`GlyphVector`を作成 - `GlyphVector#getGlyphMetrics(index)`で一文字ごとに`GlyphMetrics`を取得 -- 評価値の整数部(★一つ個分)は`GlyphMetrics#getAdvance()`で幅を取得 -- 評価値の小数部は小数点一位を`10`倍して`BigDecimal`で整数として取得し、`GlyphMetrics#getBounds2D()#getWidth() * fractionalPart / 10d`で幅に変換 - この合計幅の矩形で`Clip`した領域のみ文字列★のアウトラインを塗りつぶして評価値を描画 * 参考リンク [#reference] - [[RGBImageFilterでアイコンの色調を変更>Swing/RatingLabel]] - [[Fontのアウトラインを取得して文字列の内部を修飾する>Swing/LineSplittingLabel]] - [[Fontに長体をかけてJTextAreaで使用する>Swing/CondensedFontLabel]] * コメント [#comment] #comment #comment