" javax.swing.JPanel无法投射"例外,令人困惑

时间:2014-08-15 13:27:09

标签: java image exception

我正在尝试将图像分配给网格布局,我发现堆栈溢出的解决方案。但是我已经改变了我的代码,现在它不工作,我得到的不能被抛出异常,我不知道为什么。

下面是抛出异常的方法,特别是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();
            }
        }
    });
}

1 个答案:

答案 0 :(得分: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);}

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


修改

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

this.pnlCars.add(pnlVehicle);

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