2

BasicArrowButtonを拡張するカスタム矢印クラスがあります。必要な方法で作成および表示されますが、再描画(マウスオーバー、他のタブのクリックなど)すると矢印が消えます。どうすれば修正できますか?

public class CustomArrow extends BasicArrowButton {
private transient Color shadow = new Color(241, 241, 241);
private transient Color dark = new Color(150, 150, 150);
private static int defaultSize = 10;

/** The Polygon that points up. */
private static Polygon upIcon = new Polygon(new int[] { 0, 5, 9 },
                                          new int[] { 7, 2, 7 }, 3);

/** The Polygon that points down. */
private static Polygon downIcon = new Polygon(new int[] { 1, 8, 19 },
                                            new int[] { 3, 13, 3 }, 3);

/** The Polygon that points left. */
private static Polygon leftIcon = new Polygon(new int[] { 7, 3, 7 },
                                            new int[] { 1, 5, 9 }, 3);

/** The Polygon that points right. */
private static Polygon rightIcon = new Polygon(new int[] { 3, 7, 3 },
                                             new int[] { 1, 5, 9 }, 3);

private transient Border buttonBorder = new Border()
{
    public Insets getBorderInsets(Component c)
    {
    return new Insets(2, 2, 2, 2);
    }

  public boolean isBorderOpaque()
  {
return true;
  }

  public void paintBorder(Component c, Graphics g, int x, int y, int w, int h)
  {
  Color saved = g.getColor();
  g.setColor(shadow);

  g.drawLine(x + 1, y, x + w - 1, y);

      g.setColor(dark);
  g.drawLine(x, y, x, y + h + 2);

      g.setColor(shadow);
  g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);

  g.setColor(shadow);
      g.drawLine(x + 1, y + h - 1, x + w, y + h - 1);

  g.setColor(saved);
    }
  };  


@Override
public synchronized void addKeyListener(KeyListener l) {
    super.addKeyListener(l);
}

@Override
public void addActionListener(ActionListener l) {
    super.addActionListener(l);
}
public CustomArrow(int direction)
{
    super(direction);
    setBorder(buttonBorder);
    setDirection(direction);
    this.setRolloverEnabled(false);
}

public CustomArrow(int direction, Color background, Color shadow, Color darkShadow, Color highlight)
{
  this(direction);
  setBackground(background);
}

@Override
public void paintTriangle(Graphics g, int x, int y, int size, int direction, boolean isEnabled)
{
   Polygon arrow = null;
   switch (direction)
   {
     case NORTH:
    arrow = upIcon;
    break;
     case SOUTH:
   arrow = downIcon;
   break;
     case EAST:
     case RIGHT:
   arrow = rightIcon;
   break;
     case WEST:
     case LEFT:
   arrow = leftIcon;
   break;
  }

  int[] xPoints = arrow.xpoints;
  int[] yPoints = arrow.ypoints;
  int x1;
  int y1;
  int x2;
  int y2;
  x1 = y1 = x2 = y2 = 0;

  x = x - 1;
  if (size != defaultSize)
  {
float scale = size * 1f / defaultSize;
for (int i = 0; i < 3; i++)
  {
    xPoints[i] *= scale;
    yPoints[i] *= scale;
  }
  }
  g.translate(x, y);

  switch (direction)
  {
    case NORTH:
   x1 = xPoints[0] + 2;
   y1 = yPoints[0];
   y2 = y1;
   x2 = xPoints[2] - 1;
   break;
    case SOUTH:
   x1 = xPoints[1];
   y1 = yPoints[1] + 1;
   x2 = xPoints[2] - 1;
   y2 = yPoints[2];
   break;
    case LEFT:
    case WEST:
   x1 = xPoints[0] + 1;
   y1 = yPoints[0] + 1;
   x2 = x1;
   y2 = yPoints[2] + 1;
   break;
    case RIGHT:
    case EAST:
   x1 = xPoints[2];
   y1 = yPoints[2] + 1;
   x2 = xPoints[1] - 1;
   y2 = yPoints[1] + 1;
   break;
    }
    Color saved = g.getColor();
g.setColor(dark);

if (arrow != null) {
  g.fillPolygon(xPoints, yPoints, 3);
    }

    g.setColor(saved);
    g.translate(-x, -y);
   }

   public static void main(String[] args) {
    // Resize the frame to reproduce
    JFrame frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new CustomArrow(SwingConstants.NORTH));
    frame.setSize(400, 400);
    frame.setVisible(true);
   }
}
4

1 に答える 1

4

配列変数は、(オブジェクト変数のように)配列自体ではなく、配列への参照を保持します。あなたが次のようなことをするとき

int[] xPoints = arrow.xpoints;
int[] yPoints = arrow.ypoints;

データではなく参照をコピーしているため、xPointsとarrow.xpointsは引き続き同じデータを指し、どちらかを変更するともう一方に影響します。後でこれらのポイントを拡大縮小すると、矢印が描画されるたびに矢印がどのように表示されるかが変わります。これを回避するために配列データをコピーする場合は、次を使用できますSystem.arraycopy

int[] xPoints = new int[3]; //arrow.xpoints;
int[] yPoints = new int[3]; //arrow.ypoints;
System.arraycopy(arrow.xpoints, 0, xPoints, 0, 3);
System.arraycopy(arrow.ypoints, 0, yPoints, 0, 3);

ただし、参照ポイントをスケーリングする代わりに、グラフィックスオブジェクトを単純にスケーリングできます。

Graphics2D g2 = (Graphics2D) g;
float scale = size * 1f / defaultSize;
g2.scale(scale, scale);
于 2012-07-17T08:53:13.523 に答える