简体   繁体   中英

How do you pass an object into a new form?

Why doesn't my car object pass into my ViewCarForm?

A car gets passed into 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);
}                                         
}

The button when clicked is then supposed to pass the same car to 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());
}
}

However, the label in ViewCarForm does not get updated by the car object, so I assume that it is not passing through?

Let's look at what this constructor is doing:

public ViewCarForm(Car car){
   new ViewCarForm().setVisible(true); // (A)
   jLabel.setText(car.getMake());      // (B)
}
  • On line (A) you create a new ViewCarForm object -- and you do so within the ViewCarForm constructor, not something that I recommend that you do, since now you have two ViewCarForm instances, the original one, and a new one that you display.
  • On line (B) you set the text of a JLabel, a variable of the first and non-displayed ViewCarForm instance (I'm guessing that it's a variable of this class -- you never show us the variable declaration or instantiation. OK this will set the JLabel text of a non-displayed GUI, meanwhile the second ViewCarForm instance, the one that you do display, has no change to the text of its JLabel.
  • You don't call this() or initComponents() within the 2nd constructor, and so the code from the first default constructor, including the initComponents(); call, is never called, and so components are never properly laid out when this constructor is called.

Solution: don't do this , don't create two ViewCarForm instances, especially from within the same class's constructor. The only reason you don't have a stackoverflow error is because your class has two constructors, but even without the stackoverflow, it's insanity to do this. Create only one instance and set its JLabel text. Get rid of line (A)

Also, if the ViewCarForm is a secondary window, it shouldn't even be a JFrame but rather it should be a JDialog, either modal or non-modal depending on your need.

Also, you only init components in one ViewCarForm constructor and not in the other. So the JLabel will not show up in the second constructor/instance.

For example:

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;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM