如何将对象传递给新表单?

时间:2018-05-26 00:41:32

标签: java swing awt

为什么我的汽车对象没有进入我的ViewCarForm?

汽车被传递到InventoryItemPanel。

public class InventoryItemPanel extends JPanel{
Car car;
Button button = new Button("View More Details");



public InventoryItemPanel(Car car){

    this.car = car;

    // executes ButtonActionPerformed when button is clicked.
    button.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            ButtonActionPerformed(evt);
        }
    });
    add(button);


}

public void ButtonActionPerformed(java.awt.event.ActionEvent evt) {
    new ViewCarForm(car).setVisible(true);
}                                         
}

然后点击按钮会将同一辆车传递给ViewCarForm。

public class ViewCarForm extends javax.swing.JFrame {
Car car;


public ViewCarForm() {
    initComponents();
}

public ViewCarForm(Car car){
   new ViewCarForm().setVisible(true);
   jLabel.setText(car.getMake());
}
}

但是,ViewCarForm中的标签不会被汽车对象更新,所以我认为它没有通过?

1 个答案:

答案 0 :(得分:3)

让我们看看这个构造函数在做什么:

public ViewCarForm(Car car){
   new ViewCarForm().setVisible(true); // (A)
   jLabel.setText(car.getMake());      // (B)
}
  • 在线(A)上你创建了一个新的ViewCarForm对象 - 你在ViewCarForm构造函数中这样做,而不是我建议你做的事情,因为现在你有两个 ViewCarForm实例,原始的,一个你显示的新的。
  • 在行(B)上设置JLabel的文本,第一个和未显示的ViewCarForm实例的变量(我猜测它是这个变量的一个变量) class - 你永远不会向我们展示变量声明或实例化。确定这将设置不显示 GUI的JLabel文本,同时设置第二个ViewCarForm实例,你做的 显示,对其JLabel的文本没有变化。
  • 在第二个构造函数中调用this()initComponents(),因此来自第一个默认构造函数的代码,包括initComponents(); call,从不被调用,因此在调用此构造函数时,组件永远不会正确布局。

解决方案:不要这样做,不要创建两个ViewCarForm实例,尤其是在同一个类的构造函数中。您没有堆栈溢出错误的唯一原因是因为您的类有两个构造函数,但即使没有堆栈溢出,它也会疯狂地执行此操作。仅创建一个实例并设置其JLabel文本。 摆脱(A)行

另外,如果ViewCarForm是一个辅助窗口,它甚至不应该是一个JFrame,而应该是一个JDialog,无论是模态还是非模态,取决于你的需要。

此外,您只在一个ViewCarForm构造函数中初始化组件而不在另一个构建函数中。所以JLabel不会出现在第二个构造函数/实例中。

例如:

import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import javax.swing.*;

public class InventoryFoo extends JPanel {
    private static final Car FIRST_CAR = new Car("Honda");
    private InventoryItemPanel inventoryItemPanel = new InventoryItemPanel(FIRST_CAR);

    public InventoryFoo() {

        inventoryItemPanel.setBorder(BorderFactory.createTitledBorder("Inventory Item"));

        add(inventoryItemPanel);
    }

    private static void createAndShowGui() {
        InventoryFoo mainPanel = new InventoryFoo();

        JFrame frame = new JFrame("InventoryFoo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class InventoryItemPanel extends JPanel {
    Car car;

    // Button button = new Button("View More Details"); // should be a JButton
    JButton button = new JButton("View More Details"); // should be a JButton

    public InventoryItemPanel(Car car) {

        this.car = car;

        // executes ButtonActionPerformed when button is clicked.
        button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonActionPerformed(evt);
            }
        });
        add(button);

    }

    public void ButtonActionPerformed(java.awt.event.ActionEvent evt) {
        // new ViewCarPanel(car).setVisible(true);

        // get current JFrame
        Window thisJFrame = SwingUtilities.getWindowAncestor(this);
        // Create a non-modal JDialog
        JDialog dialog = new JDialog(thisJFrame, "Car Make", ModalityType.MODELESS);
        // create new viewCarPanel
        ViewCarPanel viewCarPanel = new ViewCarPanel(car);
        // add to dialog
        dialog.add(viewCarPanel);
        dialog.pack();
        dialog.setLocationRelativeTo(thisJFrame);
        dialog.setVisible(true);
    }
}

// better for this to be a JPanel
class ViewCarPanel extends JPanel {
    Car car;
    private JLabel jLabel = new JLabel();

    public ViewCarPanel() {
        add(new JLabel("Car Make:"));
        add(jLabel);
        setPreferredSize(new Dimension(300, 80));
    }

    public ViewCarPanel(Car car) {
        // so that we init components from the default constructor
        this(); 

        // new ViewCarPanel().setVisible(true);
        jLabel.setText(car.getMake());
    }
}

class Car {

    private String make;

    public Car(String make) {
        this.make = make;
    }

    public String getMake() {
        return this.make;
    }

}