4

これが私がやろうとしていることです。JButton を拡張し、paintComponent メソッドを上書きして、丸いエッジのボタンの目的の効果と、ボタンがマウスでロールオーバーされたときの色のフェード効果を作成しました。すべてうまくいきます。私の問題は、画像が示すように JButton がまだ白い長方形の領域をペイントしていることです。

pic1 pic1

1)白い角をなくし、2)ボタンの中心をその後ろのパネルに表示したいと思います。これが私が試したことです:

1- ボタンをペイントするときは、getParent().getBackground() を使用し、最初にボタンをペイントします。これは、不透明なパネルに最適です。ただし、このボタンが部分的または完全に透明なパネルで機能することを望みます。透明なパネルでは色がペイントされますが、白い背景ではパネルの背後にあるもの (画像など) が隠されます。

2- setOpaque(false) または setContentAreaFilled(false) の多くの組み合わせを試しました。super.paintComponent(g) を呼び出して呼び出していないときに、これを試しました。それらのどれも機能していないようです。

3- g2.clearRect(0,0,width,height) メソッド (ペイント前にグラフィックス領域をクリアする) を使用しない場合、ボタンは正しく見えますが、グラフィックス オブジェクトが覆われていないため、フェード効果は後で機能しなくなります。ボタンの 1 回のロールオーバー。

4-テキストに JLabel を使用し、不透明に設定するか、使用しないようにしましたが、問題はまだ残っています。だからそれは問題ではないと思います。

私は JButton に影響を与えるだけで他のスイング コンポーネントには影響を与えたくないので、独自の ButtonUI を作成することは避けたいと思っています。

ありがとう、そしてこれが理にかなっていることを願っています。以下は私のボタンのコードです。

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

/**
 * WButton.java
 * 
 * An extension of JButton but with custom graphics
 *
 */

public class WButton extends JButton{

  private Timer timer;
  private float[] background = {.3f,.6f,.8f,0f};
  private boolean fadeUp = true;
  private boolean fadeDown = false;
  private JLabel label;

  /**
   * Default Constructor
   */
  public WButton(){
    super();
    label = new JLabel();
    setupButton();
  }

  /**
   * Text constructor
   */
  public WButton(String text){
    super(text);
    label = new JLabel(text);
    setupButton();
  }

  /**
   * common setup functions
   */
  private void setupButton(){
    timer = new Timer(24,new TimerAction(this));
    label.setLabelFor(this);
    add(label);
  }

  /**
   * Set the background color
   */
  @Override
  public void setBackground(Color bg){
    background = bg.getRGBComponents(background);
    background[3] = 0f;
    super.setBackground(new Color(background[0],background[1],
                                  background[2],background[3]));
    repaint();
  }

  /**
   * get background
   */
  @Override
  public Color getBackground(){
    if(background!=null)
      return new Color(background[0],background[1],background[2],background[3]);

    return new Color(.5f,.5f,.5f);
  }

  /**
   * Set the font of the button
   */
  @Override
  public void setFont(Font font){
    super.setFont(font);
    if(label!=null)
      label.setFont(font);
  }

  /**
   * Override the set text method
   */
  @Override
  public void setText(String t){
    super.setText(t);
    if(label!=null)
      label.setText(t);
  }

  /**
   * Paint the button
   */
  @Override
  public void paintComponent(Graphics g){
    super.paintComponent(g);
    int width = getWidth();
    int height = getHeight();

    Graphics2D g2 = (Graphics2D)g;
    g2.clearRect(0,0,width,height);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);

    //Check Button Model state
    if(model.isPressed())
      paintPressedButton(g2,width,height);
    else{
      if(model.isRollover()){
        if(fadeUp){
          fadeUp = false;
          timer.start();
        }
      }
      else{
        if(fadeDown){
          fadeDown = false;
          timer.start();
        }
      }
      g2.setPaint(new Color(background[0],background[1],background[2],background[3]));
      g2.fillRoundRect(0,0,width-1,height-1,height,height);
    }
  }

  /**
   * Draw a pressed button
   */
  private void paintPressedButton(Graphics2D g2,int width,int height){

    float[] temp = new float[4];
    for(int i=0;i<background.length;i++)
      temp[i] = background[i]-.4f < 0f ? 0f : background[i]-.4f;

    g2.setPaint(new Color(temp[0],temp[1],temp[2],temp[3]));
    g2.fillRoundRect(0,0,width-1,height-1,height,height);

  }

  /**
   * paint the border
   */
  public void paintBorder(Graphics g){

    int width = getWidth();
    int height = getHeight();
    g.setColor(Color.BLACK);
    g.drawRoundRect(0,0,width-1,height-1,height,height);
  }

  /**
   * Inner action listener class
   */
  private class TimerAction implements ActionListener{

    private float alphaInc = .2f;
    WButton button;

    public TimerAction(WButton b){
      button = b;
    }

    public void actionPerformed(ActionEvent e){
      if(model.isRollover()){
        background[3] += alphaInc;
        if(background[3] > 1.0f){
          timer.stop();
          background[3] = 1.0f;
          fadeDown = true;
        }
      }
      else{
        background[3] -= alphaInc;
        if(background[3] < 0f){
          timer.stop();
          background[3] = 0f;
          fadeUp = true;
        }
      }
      button.repaint();
    }
  }
}

編集1

aly が提案したことで、私はさらに近づきましたが、そこまでではありませんでした。g2.clearRect() の代わりに、オブジェクトを透明な色でペイントしました。白い箱はなくなりましたが、別の色があります。調査によると、親パネルの色ですが、透明度はありません。例の写真を次に示します (パネルの透明度は 70% です)。最初の写真は、プログラムが開始されたときです。2 番目の写真は、マウスを 1 回ロールオーバーした後のものです。

pic3 ここに画像の説明を入力

4

2 に答える 2

7

あなたができることは、を使用する代わりにclearRect()、完全に透明な色で背景をクリアすることです。

g2.setColor(new Color(0,0,0,0));
g2.drawRect(0,0,width,height);

一度カーソルを合わせたら、青色のロールオーバー カラーを背景として使用しないようにsetOpaque(false)する必要があります。JButton

編集:あなたが投稿したものを見た後、問題はメインフレームが再描画されていないことだと思います.

試す:

SwingUtilities.getWindowAncestor(this).repaint();    

paint メソッドでフレームを再ペイントすると、問題が解決する場合があります。

于 2012-12-31T20:01:21.580 に答える