Search code examples
javaactionlistenerjform

There is no output in my GroceryList program


I rewrote my first application after getting the advice not to use static as much as I did and I misused inherentance. But now my application is not working anymore.

And I can't figure out why not. I think I instanciate the wrong things but can't see which things. I read about instanciation on stackoverflow and other sites but I still don't fully understand it.

I am new to java and don't code for that long. I build a layout in Netbeans. Everytime u click the "Add" button a grocery item should be displayed in the textarea. My old code (with everything being static) worked fine.

I now and then get an "Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.awt.Color" error. But its not coming up all the time. And if I don'get the error and I click the "Add" button there is just noting happening.

Could anyone tell me what I am doing wrong?

Any suggestion on what I'm doing wrong or on how I can debug this would be much appreciated.

GroceryList2ActionListener.java

    package javaclasses;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import grocerylist2jframe.GroceryList2JFrame;

    // this is the ActionListener for adding a grocery item
    public class GroceryList2ActionListener {
        public void getButtonActionAddGroceryItem() {
        GroceryList2JFrame jFrameAdd = new GroceryList2JFrame();
            jFrameAdd.buttonAddGroceryItem.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    String groceryItem = jFrameAdd.jTextField1GroceryItem.getText();
                    String quantity = jFrameAdd.jTextField2Quantity.getText();
                    String unit = jFrameAdd.jComboBox1Unit.getSelectedItem().toString();
                    jFrameAdd.jTextArea1.append(groceryItem + " " + quantity + " " + unit + "\n" );
                }
            });
        }
        // this is the ActionListener for removing a grocery item
        public void getButtonActionRemoveGroceryItem() {
            GroceryList2JFrame jFrameRemove = new GroceryList2JFrame();
            jFrameRemove.buttonRemoveGroceryItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    jFrameRemove.jTextArea1.setText(jFrameRemove.jTextArea1.getText().replaceAll(jFrameRemove.jTextArea1.getSelectedText(),""));
                }
            });
        }

        public static void main(String args[]) {
            /* Set the Nimbus look and feel */
            //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
            /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
             * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
             */
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(GroceryList2JFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>
            //</editor-fold>
            /* Create and display the form */
            java.awt.EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new GroceryList2JFrame().setVisible(true);
                }
            });
            GroceryList2ActionListener action = new GroceryList2ActionListener();
            action.getButtonActionAddGroceryItem(); // I think I call here the "addItem" and "removeItem" on button click.
            action.getButtonActionRemoveGroceryItem();
        }
    }

This is the ActionListener I wrote. And next is my layout for the application I made in Netbeans. I didn't wrote it myself I used a JForm for this.

GroceryList2JFrame.java

package grocerylist2jframe;

public class GroceryList2JFrame extends javax.swing.JFrame {

    /**
     * Creates new form GroceryList2JFrame
     */
    public GroceryList2JFrame() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jComboBox1Unit = new javax.swing.JComboBox();
        jTextField2Quantity = new javax.swing.JTextField();
        jTextField1GroceryItem = new javax.swing.JTextField();
        jPanel3 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setSize(new java.awt.Dimension(0, 0));

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Grocerylist2", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Georgia", 3, 18))); // NOI18N
        jPanel1.setFont(new java.awt.Font("Georgia", 1, 11)); // NOI18N

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Grocerylist Input", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Georgia", 3, 14))); // NOI18N

        jLabel2.setFont(new java.awt.Font("Georgia", 1, 11)); // NOI18N
        jLabel2.setText("Choose a Quantity");

        jLabel1.setFont(new java.awt.Font("Georgia", 1, 11)); // NOI18N
        jLabel1.setText("Add a Grocery Item");

        jLabel3.setFont(new java.awt.Font("Georgia", 1, 11)); // NOI18N
        jLabel3.setText("Choose A Unit");

        jComboBox1Unit.setFont(new java.awt.Font("Georgia", 1, 11)); // NOI18N
        jComboBox1Unit.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Kilogram", "Gram", "Liter", "Millilitre", "Piece(s)" }));
        jComboBox1Unit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBox1UnitActionPerformed(evt);
            }
        });

        jTextField2Quantity.setFont(new java.awt.Font("Georgia", 0, 9)); // NOI18N
        jTextField2Quantity.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField2QuantityActionPerformed(evt);
            }
        });

        jTextField1GroceryItem.setFont(new java.awt.Font("Georgia", 0, 9)); // NOI18N
        jTextField1GroceryItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1GroceryItemActionPerformed(evt);
            }
        });

        buttonAddGroceryItem.setFont(new java.awt.Font("Georgia", 1, 14)); // NOI18N
        buttonAddGroceryItem.setText("Add Grocery Item To Grocerylist");
        buttonAddGroceryItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonAddGroceryItemActionPerformed(evt);
            }
        });

        buttonRemoveGroceryItem.setFont(new java.awt.Font("Georgia", 1, 14)); // NOI18N
        buttonRemoveGroceryItem.setText("Remove Grocery Item From Gocerylist");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 135, Short.MAX_VALUE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTextField1GroceryItem)
                    .addComponent(jTextField2Quantity)
                    .addComponent(jComboBox1Unit, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
            .addComponent(buttonAddGroceryItem, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(buttonRemoveGroceryItem, javax.swing.GroupLayout.DEFAULT_SIZE, 338, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextField1GroceryItem, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(10, 10, 10)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextField2Quantity, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jComboBox1Unit, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(86, 86, 86)
                .addComponent(buttonAddGroceryItem, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(buttonRemoveGroceryItem, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(217, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Grocerylist2 View", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Georgia", 1, 14))); // NOI18N

        jTextArea1.setColumns(20);
        jTextArea1.setFont(new java.awt.Font("Georgia", 1, 11)); // NOI18N
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 391, Short.MAX_VALUE)
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1)
        );

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(13, 13, 13)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void buttonAddGroceryItemActionPerformed(java.awt.event.ActionEvent evt) {                                                     
        // TODO add your handling code here:
    }                                                    

    private void jTextField1GroceryItemActionPerformed(java.awt.event.ActionEvent evt) {                                                       
        // TODO add your handling code here:
    }                                                      

    private void jTextField2QuantityActionPerformed(java.awt.event.ActionEvent evt) {                                                    
        // TODO add your handling code here:
    }                                                   

    private void jComboBox1UnitActionPerformed(java.awt.event.ActionEvent evt) {                                               
        // TODO add your handling code here:
    }                                              

    /**
     * @param args the command line arguments
     */


    // Variables declaration - do not modify                     
    public final javax.swing.JButton buttonAddGroceryItem = new javax.swing.JButton();
    public final javax.swing.JButton buttonRemoveGroceryItem = new javax.swing.JButton();
    public javax.swing.JComboBox jComboBox1Unit;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JScrollPane jScrollPane1;
    public javax.swing.JTextArea jTextArea1;
    public javax.swing.JTextField jTextField1GroceryItem;
    public javax.swing.JTextField jTextField2Quantity;
    // End of variables declaration                   
} 

Solution

  • I think you have over-complicated this program. Other SO users are correct that you should avoid using static for methods and variables unless absolutely justified. You should read up some on Java Swing event handling and specifically on how to use ActionListener.

    In your case, you did not need a separate class (GroceryList2ActionListener), since NetBeans is creating the event handling methods for your (typically). The GroceryList2JFrame already had a method to handle adding a grocery item. For some reason, when you added the remove button, you did not select to add the action listener when building the form.

    Additionally, it makes sense to have a 'driver' class with a main to instantiate the frame, set the look-n-feel, etc.

    1) You can remove/delete the GroceryList2ActionListener class - it's no longer needed.

    2) Add this class to the same package as your GroceryList2JFrame class. This is the driver class that now has the main() method.

        package grocerylist2jframe;
    
    
        public class GroceryList {
            public static void main(String args[]) {
                System.out.println("Running the GroceryList program...");
                    /* Set the Nimbus look and feel */
                //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
                    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
                     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
                     */
                try {
                    for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            javax.swing.UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
                    java.util.logging.Logger.getLogger(GroceryList2JFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
                }
                //</editor-fold>
                //</editor-fold>
                    /* Create and display the form */
                java.awt.EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        GroceryList2JFrame frame = new GroceryList2JFrame();
                        frame.setVisible(true);
                    }
                });
            }
        }
    

    3) When building the form using NetBeans, it already added an event handler method and registered it for the add button, but it was omitted for the remove button. If you look around line 70 of the GroceryList2JFrame class you will see the method call buttonAddGroceryItem.addActionListener()... I have added a similar block to register a new method for the buttonRemoveGroceryItem. Place this block of code below the `buttonAddGroceryItem.addActionListener() code:

        buttonRemoveGroceryItem.setFont(new java.awt.Font("Georgia", 1, 14)); // NOI18N
        buttonRemoveGroceryItem.setText("Remove Grocery Item From Gocerylist");
        buttonRemoveGroceryItem.addActionListener(new java.awt.event.ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent evt){
                buttonRemoveGroceryItemActionPerformed(evt);
            }
        });
    

    Finally, you will find the existing method GroceryList2JFrame.buttonAddGroceryItemActionPerformed(), which was created by NetBeans. I have filled in the method, copying the contents from GroceryList2ActionLIstener and also added a method for the buttonRemoveGroceryItemActionPerformed(), both of which are shown below:

    private void buttonAddGroceryItemActionPerformed(java.awt.event.ActionEvent evt) {
        String groceryItem = jTextField1GroceryItem.getText();
        String quantity = jTextField2Quantity.getText();
        String unit = jComboBox1Unit.getSelectedItem().toString();
        jTextArea1.append(groceryItem + " " + quantity + " " + unit + "\n" );
    }
    
    private void buttonRemoveGroceryItemActionPerformed(java.awt.event.ActionEvent evt){
        String choice = jTextArea1.getSelectedText();
        try {
            jTextArea1.setText(jTextArea1.getText().replaceAll(choice, ""));
        }
        catch(Exception ex){
            JOptionPane.showMessageDialog(this, "Please select a valid item from the grocery list before clicking to remove.",
                    "Invalid Item selected for removal", JOptionPane.ERROR_MESSAGE);
        }
    }
    

    Once you have made these minor changes, your program should work as expected. Good Luck!