如何将图标添加到JPanel

5
所以,这是非常基础的内容,但我无法理解。我有一个CarIcon实现了Icon接口和Resizable接口(我稍后会实现它),我已经设置好了一切,但我无法弄清楚如何从主函数中将我的图标添加到JPanel或JFrame中。我的意思是,我没有组件和绘图信息来调用CarIcon类中的paintIcon方法,那该怎么办呢?
以下是一些相关的代码:
CarIcon
import java.awt.*;
import java.awt.geom.*;

public class CarIcon implements Icon, Resizable{

    private int width;
    /**
     * Construct a car of a given width.
     * @param width: the width of the car
     */
    public CarIcon(int aWidth){
        width = aWidth;
    }
    public int getIconWidth(){
        return width;
    }
    public int getIconHeight(){
        return width/2;
    }

    public void paintIcon(Component c, Graphics g, int x, int y){
        Graphics2D g2 = (Graphics2D) g;
        Rectangle2D.Double body = new Rectangle2D.Double(x, y + width / 6, width -1, width / 6);
        Ellipse2D.Double frontTire = new Ellipse2D.Double(x + width / 6, y + width / 3, width / 6, width /6);
        Ellipse2D.Double rearTire = new Ellipse2D.Double(x + width * 2 / 3, y + width / 3, width / 6, width / 6);

        // The bottom of the front windshield
        Point2D.Double r1 = new Point2D.Double(x + width / 6, y + width / 6);
        // The front of the roof
        Point2D.Double r2 = new Point2D.Double(x + width / 3, y);
        // The rear of the roof
        Point2D.Double r3 = new Point2D.Double(x + width * 2 / 3, y);
        // The bottom of the rear windshield
        Point2D.Double r4 = new Point2D.Double(x + width * 5 /6, y + width / 6);

        Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
        Line2D.Double roofTop = new Line2D.Double(r2, r3);
        Line2D.Double rearWindshield = new Line2D.Double(r3, r4);

        g2.fill(frontTire);
        g2.fill(rearTire);
        g2.setColor(Color.RED);
        g2.fill(body);
        g2.draw(frontWindshield);
        g2.draw(roofTop);
        g2.draw(rearWindshield);

    }
    @Override
    public void resize(int y) {
        // TODO Auto-generated method stub
        width += y;
    }
    @Override
    public void setIconWidth(int x) {
        // TODO Auto-generated method stub
        width = x;
    }

}

SliderTester (主函数)

import javax.swing.JFrame;
import javax.swing.JPanel;


public class SliderTester extends JPanel{

    private static final int DEFAULT_WIDTH = 400;
    private static final int DEFAULT_HEIGHT = 200;
    final static Icon myCar = new CarIcon(20);
    final static JPanel panel = new JPanel();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame frame = new JFrame();
        frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
    }


}

感谢您的帮助,提前祝您复活节快乐!

以下方法无法正常工作:

final static Icon myCar = new CarIcon(20);
final static JLabel label = new JLabel(myCar);

编译器说:“JLabel(Icon)构造函数未定义”

另一个编辑:

我的Eclipse可能出了问题吗?下面是一张屏幕截图,我将您的代码复制到我的程序中,它会抛出错误:

enter image description here

1个回答

6

图标自然不会直接添加到 JPanels,但它们可以自然和轻松地添加到 JLabels 中,然后 JLabels 可以轻松地添加到 JPanel 中。我认为这正是你应该采取的做法:

  • 使用您的 Icon 创建一个 JLabel。您可以通过将 Icon 传递到 JLabel 的构造函数中或在 JLabel 上调用 setIcon(...) 来实现此操作。
  • 使用您需要的任何适当的布局管理器将 JLabel 添加到您的 JPanel 中
  • 将该 JPanel 添加到另一个 JPanel 或顶层窗口或任何需要的位置。

如果您已经正确实现了您的 Icon,则应该进行如下操作:

JLabel myLabel = new JLabel(myIcon);
myPanel.add(myLabel);

或者以您的代码为例:
  JLabel label = new JLabel(myCar);
  panel.add(label);

  JFrame frame = new JFrame();
  frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
  frame.add(panel);

更简单地说:
public static void main(String[] args) {
  SwingUtilities.invokeLater(new Runnable() {
     public void run() {
        JLabel label = new JLabel(new CarIcon(40));
        JPanel panel = new JPanel();
        panel.add(label);
        JOptionPane.showMessageDialog(null, panel);
     }
  });
}

这是我的整个测试程序:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class TestCarIcon {

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            JLabel label = new JLabel(new CarIcon(80));
            JPanel panel = new JPanel();
            panel.add(label);
            JOptionPane.showMessageDialog(null, panel);
         }
      });
   }

}

class CarIcon implements Icon, Resizable {

   private int width;

   /**
    * Construct a car of a given width.
    * 
    * @param width
    *           : the width of the car
    */
   public CarIcon(int aWidth) {
      width = aWidth;
   }

   public int getIconWidth() {
      return width;
   }

   public int getIconHeight() {
      return width / 2;
   }

   public void paintIcon(Component c, Graphics g, int x, int y) {
      Graphics2D g2 = (Graphics2D) g;

      // !! Added to smooth images
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      Rectangle2D.Double body = new Rectangle2D.Double(x, y + width / 6,
            width - 1, width / 6);
      Ellipse2D.Double frontTire = new Ellipse2D.Double(x + width / 6, y
            + width / 3, width / 6, width / 6);
      Ellipse2D.Double rearTire = new Ellipse2D.Double(x + width * 2 / 3, y
            + width / 3, width / 6, width / 6);

      // The bottom of the front windshield
      Point2D.Double r1 = new Point2D.Double(x + width / 6, y + width / 6);
      // The front of the roof
      Point2D.Double r2 = new Point2D.Double(x + width / 3, y);
      // The rear of the roof
      Point2D.Double r3 = new Point2D.Double(x + width * 2 / 3, y);
      // The bottom of the rear windshield
      Point2D.Double r4 = new Point2D.Double(x + width * 5 / 6, y + width / 6);

      Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
      Line2D.Double roofTop = new Line2D.Double(r2, r3);
      Line2D.Double rearWindshield = new Line2D.Double(r3, r4);

      g2.fill(frontTire);
      g2.fill(rearTire);
      g2.setColor(Color.RED);
      g2.fill(body);
      g2.draw(frontWindshield);
      g2.draw(roofTop);
      g2.draw(rearWindshield);

   }

   @Override
   public void resize(int y) {
      width += y;
   }

   @Override
   public void setIconWidth(int x) {
      width = x;
   }

}

interface Resizable {
   void resize(int y);

   void setIconWidth(int x);
}

这显示了这个:

在此输入图像描述


嗯,您能详细说明一下吗?我在使用JLabel时遇到了与JPanel相同的问题。我不能简单地使用label.add(myCar)。我是否错过了某些解决方法?我的车不是一个图像(它实现了Icon接口)。 - aurora91
@aurora91:你看到了什么错误?请发布完整的消息。我还发布了一个运行程序时所看到的图像。 - Hovercraft Full Of Eels
"The constructor JLabel(CarIcon) is undefined",建议从JLabel中删除参数。是的,这就是我想要的图像。之后,我想能够使用滑动条调整其大小。但是,正如您所看到的,我甚至无法让它出现。 - aurora91
是的,有时候我可能会有点傻傻的...抱歉。 - aurora91
@aurora91:你身处优秀的公司,欢迎加入我的 derp 俱乐部。 - Hovercraft Full Of Eels
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接