概要

ConvolveOpを使って、使用不可状態のJButtonにぼかしを入れます。

サンプルコード

class BlurButton extends JButton {
  private final ConvolveOp op = new ConvolveOp(
      new Kernel(3, 3, new float[] {
    .05f, .05f, .05f,
    .05f, .60f, .05f,
    .05f, .05f, .05f
  }), ConvolveOp.EDGE_NO_OP, null);
  private BufferedImage buf;

  public BlurButton(String label) {
    super(label);
    // System.out.println(op.getEdgeCondition());
  }

  @Override protected void paintComponent(Graphics g) {
    if (isEnabled()) {
      super.paintComponent(g);
    } else {
      int w = getWidth();
      int h = getHeight();
      buf = Optional.ofNullable(buf)
          .filter(bi -> bi.getWidth() == w && bi.getHeight() == h)
          .orElseGet(() -> new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB));
      Graphics2D g2 = buf.createGraphics();
      g2.setFont(g.getFont()); // pointed out by 八ツ玉舘
      super.paintComponent(g2);
      g2.dispose();
      g.drawImage(op.filter(buf, null), 0, 0, null);
    }
  }

  // @Override public Dimension getPreferredSize() {
  //   Dimension d = super.getPreferredSize();
  //   d.width += 3 * 3;
  //   return d;
  // }
}
View in GitHub: Java, Kotlin

解説

    • デフォルトのJButton
    • WindowsLookAndFeelの場合、右端1ドットの表示が乱れる場合があるのでEdgeConditionをデフォルトのEDGE_ZERO_FILLからEDGE_NO_OPに変更
    • WindowsLookAndFeelの場合、これらのぼかしを入れると文字が拡大されて?(左右のBorderが広いから?)文字列が省略されてしまうのでJButton#getPreferredSize()をオーバーライドして幅を拡大
      • コメントで八ツ玉舘さんから指摘があり、文字が拡大されるのはBufferedImageから生成したGraphicsとコンポーネントのGraphicsで異なるフォントが設定されていることが原因と判明
      • g2.setFont(g.getFont());を使用するよう修正

参考リンク

コメント