【问题标题】:"javax.swing.JPanel cannot be cast" exception, confusing“javax.swing.JPanel 无法强制转换”异常,令人困惑
【发布时间】:2014-08-15 21:44:22
【问题描述】:

我正在尝试将图像分配给网格布局,但我找到了堆栈溢出的解决方案。但是,我更改了我的代码,现在它无法正常工作,我得到了不能强制转换的异常,我不确定为什么。

下面是抛出异常的方法,具体是imagePanel这一行:

public void setVehicle(int x, int y, Vehicle vehicle) {
    this.vehicles[x][y] = vehicle;
    ImageIcon image;
    if (vehicle != null) {
        image = vehicle.getImage();
    } else {
        image = null;
    }
    ((ImagePanel) this.pnlCars.getComponent(x + (y - 1) * (this.vehicles.length - 1))).setImage(image);}

这是下面的图像面板类:

public class ImagePanel extends JPanel{
private ImageIcon image;

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (image != null) {
        // Center icon
        int width = this.getWidth();
        int height = this.getHeight();
        int iconWidth = image.getIconWidth();
        int iconHeight = image.getIconHeight();
        g.drawImage(image.getImage(), (width - iconWidth) / 2, (height - iconHeight) / 2, null);
    }
}

public void setImage(ImageIcon image) {
    this.image = image;
    this.repaint();
}

}

这是错误信息:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JPanel cannot be cast to carparkingprogram.gui.ImagePanel
    at carparkingprogram.gui.CarParkPanel.setVehicle(CarParkPanel.java:197)
    at carparkingprogram.gui.CarParkPanel$7$1.actionPerformed(CarParkPanel.java:325)

有人可以帮忙吗?

这是完整的代码,显然我已经尝试让它尽可能小,所以我只包括了汽车部分。

public static int ROWS_LARGE = 1;
public static int ROWS_SMALL = 3;
public static int ROWS = ROWS_LARGE + ROWS_SMALL;
public static int COLUMNS = 4;
public Vehicle[][] vehicles = new Vehicle[ROWS][COLUMNS];


public CarParkPanel() {
    this.setLayout(new BorderLayout());

    pnlButtons = new JPanel();
    pnlButtons.setLayout(null);
    pnlButtons.setLayout(new BoxLayout(pnlButtons, BoxLayout.Y_AXIS));

    pnlButtons.add(btnAddCar);
    addCarMethod();

    this.add(pnlButtons);


    this.pnlLorry = new JPanel();
    this.pnlLorry.setLayout(new GridLayout(ROWS_LARGE, COLUMNS));
    this.pnlLorry.setPreferredSize(new Dimension(400, 200));

    this.pnlCars = new JPanel();
    this.pnlCars.setLayout(new GridLayout(ROWS_SMALL, COLUMNS));
    this.pnlCars.setPreferredSize(new Dimension(400, 300));

//This is the code to create the grid panel that the images are added to
    for (int row = 0; row < ROWS; row++) {
        for (int column = 0; column < COLUMNS; column++) {
            JPanel pnlVehicle = new JPanel(new BorderLayout());
            pnlVehicle.setBorder(BorderFactory.createLineBorder(Color.RED));
            pnlVehicle.addMouseListener(new MyMouseListener(column, (row * ROWS)));

            if (row < ROWS_LARGE) {
                this.pnlLorry.add(pnlVehicle);
            } else {
                this.pnlCars.add(pnlVehicle);
            }
        }
    }


    this.add(pnlButtons, BorderLayout.WEST);
    this.pnlVehicles = new JPanel(new BorderLayout());
    this.pnlVehicles.setPreferredSize(new Dimension(400, 500));
    this.pnlVehicles.add(this.pnlLorry, BorderLayout.NORTH);
    this.pnlVehicles.add(this.pnlCars, BorderLayout.AFTER_LAST_LINE);
    this.add(this.pnlVehicles, BorderLayout.EAST);


}

public int[] findEmptySpace(int start, int end) {
    for (int row = 0; row < vehicles.length; row++) {
        for (int column = start; column < end; column++) {
            //Check if space is empty
            if (this.getVehicle(row, column) == null) {
                return new int[]{
                    row,
                    column
                };
            }
        }
    }
    return null;
}


public void setVehicle(int x, int y, Vehicle vehicle) {
    this.vehicles[x][y] = vehicle;

    //TODO: Render vehicle in GUI. Check for null and remove
    ImageIcon image;
    if (vehicle != null) {
        image = vehicle.getImage();
    } else {
        image = null;
    }
    ((ImagePanel) this.pnlCars.getComponent(x + (y - 1) * (this.vehicles.length - 1))).setImage(image);

    //TODO: Update totals

}

public Vehicle getVehicle(int x, int y) {
    return this.vehicles[x][y];
}

private void addCarMethod() {
    btnAddCar.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            //TODO: Create car input form.
            //REQUIREMENTS: registration, length, disabled


            final int[] value = findEmptySpace(1, vehicles.length);
            if (value != null) {
                //SHOW FORM

                final JFrame frame = new JFrame("Add Car");
                frame.setSize(350, 150);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                Labels = new GridLayout(4, 2);
                FormLayout = new GridLayout(2, 1);

                pnlForm = new JPanel();
                pnlFormButton = new JPanel();
                frame.setLayout(FormLayout);
                frame.add(pnlForm);
                frame.add(pnlFormButton);
                pnlForm.setLayout(null);

                pnlForm.setLayout(Labels);
                JLabel reg = new JLabel("Registration Number:");
                pnlForm.add(reg);

                final JTextField regTxt = new JTextField(20);
                pnlForm.add(regTxt);

                JLabel length = new JLabel("Length: ");
                pnlForm.add(length);

                final JTextField lengthTxt = new JTextField(20);
                pnlForm.add(lengthTxt);

                JLabel disBadge = new JLabel("Disabled Badge: ");
                pnlForm.add(disBadge);

                final JTextField disBadgeTxt = new JTextField(20);
                pnlForm.add(disBadgeTxt);

                JButton ok = new JButton("Ok");
                pnlFormButton.setLayout(FormLayout);
                pnlFormButton.add(ok);
                frame.setVisible(true);

                ok.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                        String regNumber = regTxt.getText();
                        System.out.println("ok");
                        double length = Double.parseDouble(lengthTxt.getText());
                        boolean BadgeBoolean;

                        if (disBadgeTxt.equals("yes")) {
                            BadgeBoolean = true;
                        } else {
                            BadgeBoolean = false;
                        }

                        Car vehicle = new Car(regNumber, length, BadgeBoolean, 1);
                        System.out.println(String.valueOf(value[0]) + ":" + String.valueOf(value[1]));
                        setVehicle(value[0], value[1], vehicle);

                        frame.dispose();
                    }
                });

            } else {
                warningMethod();
            }
        }
    });
}

【问题讨论】:

  • 如果您能分享如何将组件添加到 CarParkPanel.pnlCars 字段,可能会有所帮助。

标签: java image exception


【解决方案1】:

你的问题是这一行:

this.pnlCars.getComponent(x + (y - 1) * (this.vehicles.length - 1))

正在返回一个 JPanel 实例,而不是一个 ImagePanel 实例,并且您发布的代码中未显示此原因。以这种方式使用getComponent(...) 是一件危险而脆弱的事情,如果我们能更多地了解您的程序,可能会有更好的方法。为了获得更好的帮助,请考虑创建并发布Minimal, Complete, and Verifiable Example Program,在其中将代码压缩为仍可编译和运行的最小位,没有外部依赖项(例如需要链接到数据库或图像),没有额外的代码与您的问题相关,但仍能证明您的问题。

顺便说一句,那行有问题的代码,

((ImagePanel) this.pnlCars.getComponent(x + (y - 1) * (this.vehicles.length - 1)))
      .setImage(image);}

太长了,并且尝试做太多事情,使调试变得比需要的更困难。代码空间很便宜,因此将其分成几行,以便于阅读和调试。


编辑

您正在将 JPanel(此处称为 pnlVehicle)添加到您的 pnlCars JPanel 对象中:

this.pnlCars.add(pnlVehicle);

因此,如果您尝试从 pnlVehicle JPanel 中提取一个组件,那么它实际上是一个 JPanel 而不是 ImagePanel(无论是什么),这是完全合理的。您的错误应该不会让您感到惊讶。

【讨论】:

  • 我刚刚上传了完整的代码(我已经压缩了):)
  • @RebeccaWilde:谢谢,但最好创建和发布minimal code example,而不是不可编译和不可运行的代码 sn-p。请阅读链接,因为它将解释为什么这很重要以及要求是什么。
  • 谢谢。我设法找出我哪里出错了!图像面板部分是一个将图像分配给 jpanel 的类,我只是在程序的早期没有正确初始化它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多