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

数组变量保存对数组的引用,而不是数组本身(就像 Object 变量一样)。当你做类似的事情时

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 回答