I'm brand spanking new to Swing in Java as I am more familiar with JavaFX. However, my professor wants me to use Swing for an assignment.
I'm a bit stupefied at the moment, because for some reason, my method to add and append to a TextArea in swing is not working. I'm getting a runtime error upon clicking the add button button within my Application. Runtime error is the following:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at PlantGUIDriverFinalAssignment.addFlower(PlantGUIDriverFinalAssignment.java:170)
at PlantGUIDriverFinalAssignment.access$100(PlantGUIDriverFinalAssignment.java:11)
at PlantGUIDriverFinalAssignment$ButtonHandlerAdd.actionPerformed(PlantGUIDriverFinalAssignment.java:326)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Thus far, I can't add an instance of my plant Object or subclass Flower to the text area because of the runtime Error. Here is the GUI code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Font;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class PlantGUIDriverFinalAssignment extends JFrame {
JRadioButton rdoBtnPlant, rdoBtnFlower, rdoBtnHerb, rdoBtnWeed, rdoBtnFungus;
JCheckBox isPoisonous, isEdible, isMedicinal, isNicelyFlavored, isSeasonal, hasThorns, smellsNice;
JButton btnAdd, btnRemove, btnFilter, btnClear, btnSort;
JTextField txtPlantID, txtColor, txtName;
JScrollPane scrollPane;
JTextArea plantSummary;
String plantColor, plantName, plantID;
ArrayList<Plant> plantList;
public PlantGUIDriverFinalAssignment() {
try {
this.setTitle("Plant Interface");
setLayout(new FlowLayout());
JPanel plantPanel1 = new JPanel(); //Create a Pane to add components within them to better organize the UI
JPanel plantPanel2 = new JPanel(); //Create another Panel to hold more plant components (checkboxes, etc)
JPanel plantPanel3 = new JPanel(); //Create this panel to hold buttons.
JPanel plantPanel4 = new JPanel(new BorderLayout()); //Create this Panel to hold TextArea plantSummary
rdoBtnPlant = new JRadioButton("Plant");
rdoBtnFlower = new JRadioButton("Flower");
rdoBtnWeed = new JRadioButton("Weed");
rdoBtnHerb = new JRadioButton("Herb");
rdoBtnFungus = new JRadioButton("Fungus");
rdoBtnPlant.setSelected(true);
//Create a group of Radio Buttons
ButtonGroup plantSelection = new ButtonGroup();
plantSelection.add(rdoBtnPlant);
plantSelection.add(rdoBtnFlower);
plantSelection.add(rdoBtnHerb);
plantSelection.add(rdoBtnWeed);
plantSelection.add(rdoBtnFungus);
JLabel plantSelectLabel = new JLabel("Please select from the following plants to add below: ");
plantSelectLabel.setFont(new Font("Serif", 20, 20));
//Add radio buttons to contentPane
add(plantSelectLabel);
add(rdoBtnPlant);
add(rdoBtnFlower);
add(rdoBtnWeed);
add(rdoBtnHerb);
add(rdoBtnFungus);
rdoBtnPlant.addActionListener(new RadioHandler());
rdoBtnFlower.addActionListener(new RadioHandler());
rdoBtnHerb.addActionListener(new RadioHandler());
rdoBtnWeed.addActionListener(new RadioHandler());
rdoBtnFungus.addActionListener(new RadioHandler());
JLabel clrLabel = new JLabel("Enter Color:");
JTextField txtColor = new JTextField("",15);
JLabel plantIdentity = new JLabel("Enter Name:");
JTextField txtName = new JTextField("",15);
JLabel idLabel = new JLabel("Enter ID:");
JTextField txtPlantID = new JTextField("", 15);
plantPanel1.add(clrLabel);
plantPanel1.add(txtColor);
plantPanel1.add(plantIdentity);
plantPanel1.add(txtName);
plantPanel1.add(idLabel);
plantPanel1.add(txtPlantID);
add(plantPanel1);
//Create CheckBoxes for Boolean value representations (0 and 1 / True or False)
JLabel traits = new JLabel("Traits:");
isPoisonous = new JCheckBox("Poisonous");
isEdible = new JCheckBox("Edible");
isMedicinal = new JCheckBox("Medicinal");
isNicelyFlavored = new JCheckBox("Nice Flavor");
isSeasonal = new JCheckBox("Seasonal");
hasThorns = new JCheckBox("Thorny");
smellsNice = new JCheckBox("Smells Nice");
isPoisonous.setEnabled(false);
isEdible.setEnabled(false);
isMedicinal.setEnabled(false);
isNicelyFlavored.setEnabled(false);
isSeasonal.setEnabled(false);
hasThorns.setEnabled(false);
smellsNice.setEnabled(false);
plantPanel2.add(traits);
plantPanel2.add(isPoisonous);
plantPanel2.add(isEdible);
plantPanel2.add(isMedicinal);
plantPanel2.add(isNicelyFlavored);
plantPanel2.add(isSeasonal);
plantPanel2.add(hasThorns);
plantPanel2.add(smellsNice);
add(plantPanel2);
btnAdd = new JButton("Add");
btnRemove = new JButton("Remove");
btnSort = new JButton("Sort");
btnFilter = new JButton("Filter");
btnClear = new JButton("Clear");
btnAdd.addActionListener(new ButtonHandlerAdd());
plantPanel3.add(btnAdd);
plantPanel3.add(btnRemove);
plantPanel3.add(btnSort);
plantPanel3.add(btnFilter);
plantPanel3.add(btnClear);
plantSummary = new JTextArea(10,20);
plantSummary.setBackground(Color.WHITE);
plantSummary.setFont(new Font("Verdana",Font.PLAIN, 20));
plantSummary.setEditable(false);
plantSummary.setVisible(true);
scrollPane = new JScrollPane(plantSummary);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
plantPanel4.add(scrollPane, BorderLayout.SOUTH);
add(plantPanel3);
add(plantPanel4);
setSize(900, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
} catch(Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
new PlantGUIDriverFinalAssignment();
}
private void addPlant() {
//Add a plant that is specified by the user
plantName = txtName.getText();
plantColor = txtColor.getText();
plantID = txtPlantID.getText();
Plant thePlant = new Plant(plantColor, plantID, plantName);
plantList.add(thePlant);
plantSummary.append(thePlant.toString());
}
private void addFlower() {
//Add a plant that is specified by the user
String flowerName;
String flowerColor;
String flowerID;
boolean scentType;
boolean isThorny;
flowerName = txtName.getText();
flowerColor = txtColor.getText();
flowerID = txtPlantID.getText();
isThorny = hasThorns.isSelected();
scentType = smellsNice.isSelected();
Flower theFlower = new Flower(flowerColor, flowerID, flowerName, scentType, isThorny);
plantList.add(theFlower);
plantSummary.append(theFlower.toString());
}
class RadioHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Plant")) {
isPoisonous.setEnabled(false);
isEdible.setEnabled(false);
isMedicinal.setEnabled(false);
isNicelyFlavored.setEnabled(false);
isSeasonal.setEnabled(false);
hasThorns.setEnabled(false);
smellsNice.setEnabled(false);
} else if (e.getActionCommand().equals("Fungus")) {
isPoisonous.setEnabled(true);
isEdible.setEnabled(false);
isMedicinal.setEnabled(false);
isNicelyFlavored.setEnabled(false);
isSeasonal.setEnabled(false);
hasThorns.setEnabled(false);
smellsNice.setEnabled(false);
} else if (e.getActionCommand().equals("Weed")) {
isPoisonous.setEnabled(true);
isEdible.setEnabled(true);
isMedicinal.setEnabled(true);
isNicelyFlavored.setEnabled(false);
isSeasonal.setEnabled(false);
hasThorns.setEnabled(false);
smellsNice.setEnabled(false);
} else if (e.getActionCommand().equals("Flower")) {
hasThorns.setEnabled(true);
smellsNice.setEnabled(true);
isPoisonous.setEnabled(false);
isMedicinal.setEnabled(false);
isSeasonal.setEnabled(false);
isNicelyFlavored.setEnabled(false);
isEdible.setEnabled(false);
} else if (e.getActionCommand().equals("Herb")) {
isPoisonous.setEnabled(false);
isEdible.setEnabled(false);
isMedicinal.setEnabled(true);
isNicelyFlavored.setEnabled(true);
isSeasonal.setEnabled(true);
hasThorns.setEnabled(false);
smellsNice.setEnabled(false);
}
}
}
class ButtonHandlerAdd implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Add Button Clicked!");
if (e.getActionCommand().equals("Add") && rdoBtnPlant.isSelected()) {
addPlant();
} else if (e.getActionCommand().equals("Add") && rdoBtnFlower.isSelected()) {
addFlower();
}
}
}
/* class TextFieldVariable implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("TextFields listening");
plantColor = txtColor.getText();
plantID = txtPlantID.getText();
plantName = txtName.getText();
}
}*/
}
Here is the Plant Class in case if you are wondering:
public class Plant {
private String id;
private String name;
private String color;
public Plant() {
this.id = "";
this.name = "";
this.color = "";
}
public Plant(String plantColor, String plantID, String plantName) {
this.id = plantID;
this.color = plantColor;
this.name = plantName;
}
public void setID(String plantID) {
this.id = plantID;
}
public void setColor(String plantColor) {
this.color = plantColor;
}
public void setName(String plantName) {
this.name = plantName;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
public String getID() {
return id;
}
public String toString() {
return "This plant's name is " + this.getName() + " with a color of: " + this.getColor() +
" with a unique ID of: " + this.getID();
}
@Override
public boolean equals(Object otherPlant) {
if (otherPlant == null) {
return false;
}
if (!Plant.class.isAssignableFrom(otherPlant.getClass())) {
return false;
}
final Plant other = (Plant) otherPlant;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if (!(this.color.equals(other.color))) {
return false;
}
if (!(this.id.equals(other.id))) {
return false;
}
return true;
}
}
I don't know why the code is getting the runtime error. Where am I going wrong? Thanks. Apologies in advance if the question isn't clear enough.