Reputation: 75
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?
Upvotes: 1
Views: 103
Reputation: 285430
Let's look at what this constructor is doing:
public ViewCarForm(Car car){
new ViewCarForm().setVisible(true); // (A)
jLabel.setText(car.getMake()); // (B)
}
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;
}
}
Upvotes: 3