1

I'm trying to create a simple program to manage Employees. When trying to add a new employee I can't seem to get the employee to be displayed on the Jlist.

The main frame...

public class EmployeeFrame extends JFrame implements ActionListener {

    // The buttons to display
    private JButton addButton;
    private JButton editButton;
    private JButton deleteButton;
    private JButton saveButton;

    // The underlying list of employees, and the GUI object to display them
    private DefaultListModel<Employee> listModel;
    private JList<Employee> employeeList;

    public static final String SAVE_FILE = "employees.txt";

    /**
     * Creates and displays a new EmployeeFrame. The program exits when the
     * window is closed.
     */
    public EmployeeFrame() {
        // Basic window features
        super("Employee Manager");
        setLocationByPlatform(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // Try to make it look like a native application -- using try/multi-catch
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        // Initialise an empty list model, a JList to display it, and a scroll
        // pane to contain the list
        listModel = new DefaultListModel<>();
        employeeList = new JList<>(listModel);
        JScrollPane employeeScroll = new JScrollPane(employeeList);
        employeeScroll.setBorder(new TitledBorder("Employee List"));

        // Initialise all buttons and add the current class as an action
        // listener to all
        addButton = new JButton("Add Employee");
        addButton.addActionListener(this);
        editButton = new JButton("Edit Employee");
        editButton.addActionListener(this);
        deleteButton = new JButton("Delete Employee");
        deleteButton.addActionListener(this);
        saveButton = new JButton("Save Employee List");
        saveButton.addActionListener(this);

        // Lay out the buttons in a line
        Box topBox = Box.createHorizontalBox();
        topBox.add(addButton);
        topBox.add(Box.createHorizontalStrut(10));
        topBox.add(editButton);
        topBox.add(Box.createHorizontalStrut(10));
        topBox.add(deleteButton);
        topBox.add(Box.createHorizontalStrut(10));
        topBox.add(saveButton);

        // Lay out the window
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(topBox, BorderLayout.NORTH);
        getContentPane().add(employeeScroll, BorderLayout.CENTER);
        pack();
    }


    public DefaultListModel<Employee> getListModel() {
        return this.listModel;
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        // Determine which button was pushed
        Object source = event.getSource();

        // Here's what to do with the delete button
        if (source == deleteButton) {
            Employee selection = employeeList.getSelectedValue();
            if (selection != null) {
                listModel.removeElement(selection);
            }
        }

        if (source == addButton) {
            AddEmployeeDialog frame = new AddEmployeeDialog(new EmployeeFrame());
            frame.setVisible(true);

        }

    }

    public static void main(String[] args) {
        new EmployeeFrame().setVisible(true);
    }

}

The dialogue that adds the employee...

public class AddEmployeeDialog extends JDialog implements ActionListener {

    // Common fields
    private JComboBox<String> workerType;
    private JTextField givenNameField;
    private JTextField familyNameField;
    private JDatePicker startDatePicker;

    // Fields that depend on the employee type
    private JTextField rateField;
    private JTextField hoursField;
    private JTextField salaryField;

    // Buttons
    private JButton okButton;
    private JButton cancelButton;

    // The employee frame -- used to position the dialog and to access the
    // employee list
    private EmployeeFrame employeeFrame;


    public AddEmployeeDialog(final EmployeeFrame frame) {
        // Basic initialisation
        super(frame, "Add Employee", true);
        setLocationRelativeTo(employeeFrame);
        this.employeeFrame = frame;

        // Common fields
        workerType = new JComboBox<String>(Employee.getEmployeeTypes());
        givenNameField = new JTextField(20);
        familyNameField = new JTextField(20);
        startDatePicker = new JDateComponentFactory().createJDatePicker();

        // Fields only for hourly workers
        rateField = new JTextField(10);
        hoursField = new JTextField(5);

        // Field only for salaried worker
        salaryField = new JTextField(10);

        // Top line
        Box workerBox = Box.createHorizontalBox();
        workerBox.add(new JLabel("Worker type"));
        workerBox.add(workerType);
        workerBox.add(new JLabel("Start date"));
        workerBox.add((JPanel) startDatePicker);

        // Next lines (names)
        Box givenNameBox = Box.createHorizontalBox();
        givenNameBox.add(new JLabel("Given name "));
        givenNameBox.add(givenNameField);

        Box familyNameBox = Box.createHorizontalBox();
        familyNameBox.add(new JLabel("Family name"));
        familyNameBox.add(familyNameField);

        // Hourly-worker fields
        Box hourlyBox = Box.createHorizontalBox();
        hourlyBox.setBorder(new TitledBorder("Hourly worker information"));
        hourlyBox.add(new JLabel("Rate"));
        hourlyBox.add(rateField);
        hourlyBox.add(Box.createHorizontalStrut(10));
        hourlyBox.add(new JLabel("Hours"));
        hourlyBox.add(hoursField);

        // Salaried-worker fields
        Box salariedBox = Box.createHorizontalBox();
        salariedBox.setBorder(new TitledBorder("Salaried worker information"));
        salariedBox.add(new JLabel("Salary"));
        salariedBox.add(salaryField);

        // Ensure that only the appropriate fields are enabled, depending on the
        // worker type chosen
        workerType.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent arg0) {
                String type = (String) workerType.getSelectedItem();
                salaryField.setEnabled("Salaried".equals(type));
                rateField.setEnabled("Hourly".equals(type));
                hoursField.setEnabled("Hourly".equals(type));
            }
        });
        workerType.setSelectedItem(null);

        // Create buttons and add the current class as an ActionListener
        okButton = new JButton("OK");
        okButton.addActionListener(this);
        cancelButton = new JButton("Cancel");
        cancelButton.addActionListener(this);

        // Bottom row of GUI: buttons
        Box bottomBox = Box.createHorizontalBox();
        bottomBox.add(Box.createHorizontalGlue());
        bottomBox.add(okButton);
        bottomBox.add(Box.createHorizontalGlue());
        bottomBox.add(cancelButton);
        bottomBox.add(Box.createHorizontalGlue());

        // Lay out the GUI
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        getContentPane().add(workerBox);
        getContentPane().add(givenNameBox);
        getContentPane().add(familyNameBox);
        getContentPane().add(hourlyBox);
        getContentPane().add(salariedBox);
        getContentPane().add(Box.createVerticalStrut(10));
        getContentPane().add(bottomBox);
        pack();
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        // Convert the value from the date picker into a LocalDate
        GregorianCalendar startDateValue = (GregorianCalendar) startDatePicker.getModel().getValue();
        LocalDate startDate = startDateValue.toZonedDateTime().toLocalDate();

        // Work out which button was pressed
        Object source = event.getSource();

        if (source == cancelButton) {
            // Just close the window
            dispose();
        }

        if (source == okButton) {
            // Determine if the employee is hourly or salaried
            if (workerType.getSelectedItem().toString() == "Salaried") {
                // Create new salaried employee 
                if (salaryField.getText().matches("[0-9]+")) {
                    Employee employee = new SalariedEmployee(givenNameField.getText(), 
                                                             familyNameField.getText(),
                                                             startDate,
                                                             Double.parseDouble(salaryField.getText()));
                    employeeFrame.getListModel().addElement(employee);
                }
            }
            else {
                // Create new hourly employee
                if (rateField.getText().matches("[0-9]+") && hoursField.getText().matches("[0-9]+")) {
                    Employee employee = new HourlyEmployee(givenNameField.getText(), 
                                                           familyNameField.getText(), 
                                                           startDate, 
                                                           Double.parseDouble(rateField.getText()),
                                                           Integer.parseInt(hoursField.getText()));
                    employeeFrame.getListModel().addElement(employee);
                }

            }
            dispose();      
        }       
    }

}

This is what I'm using to add the employee

employeeFrame.getListModel().addElement(employee);

I think this is the right method but it doesn't seem to work. Any help will really be appreciated.

sambebop
  • 13
  • 4
  • bad: `if (workerType.getSelectedItem().toString() == "Salaried") {`. Use `equals(...)` or `equalsIgnoreCase(...)`. Understand that `==` checks for *reference* equality which is most definitely **not** what you're interested in. You want functional equality which is what the methods test for. – Hovercraft Full Of Eels Dec 01 '15 at 22:16
  • So: `if ("Salaried".equalsIgnoreCase(workerType.getSelectedItem().toString())) {` – Hovercraft Full Of Eels Dec 01 '15 at 22:22
  • Thanks for that, I'll add that change now, but that was not my original question. I don't know why this has been marked as duplicate and sending me to http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – sambebop Dec 01 '15 at 22:27
  • I marked it a duplicate because you in fact do have a problem that is discussed in that question, but that's not the only problem in your code. – Hovercraft Full Of Eels Dec 01 '15 at 22:32
  • Please see edits to answer. – Hovercraft Full Of Eels Dec 01 '15 at 22:35

1 Answers1

2

Two problems,
The first:

bad: if (workerType.getSelectedItem().toString() == "Salaried") {. Use equals(...) or equalsIgnoreCase(...). Understand that == checks for reference equality which is most definitely not what you're interested in. You want functional equality which is what the methods test for.

So: if ("Salaried".equalsIgnoreCase(workerType.getSelectedItem().toString())) {

The second:

AddEmployeeDialog frame = new AddEmployeeDialog(new EmployeeFrame());

You're passing in a new EmployeeFrame object meaning you're updating the list model for the wrong EmployeeFrame. Instead pass in the visualized EmployeeFrame.

Change it to:

AddEmployeeDialog frame = new AddEmployeeDialog(EmployeeFrame.this);

My program that I created to shrink your code but still allow it to be runnable and to demonstrate your problem:

import java.awt.BorderLayout;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.TitledBorder;

@SuppressWarnings("serial")
public class EmployeeFrame extends JFrame implements ActionListener {
    private JButton addButton;

    private DefaultListModel<Employee> listModel;
    private JList<Employee> employeeList;

    public EmployeeFrame() {
        super("Employee Manager");
        setLocationByPlatform(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        listModel = new DefaultListModel<>();
        employeeList = new JList<>(listModel);
        JScrollPane employeeScroll = new JScrollPane(employeeList);
        employeeScroll.setBorder(new TitledBorder("Employee List"));

        addButton = new JButton("Add Employee");
        addButton.addActionListener(this);

        Box topBox = Box.createHorizontalBox();
        topBox.add(addButton);

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(topBox, BorderLayout.NORTH);
        getContentPane().add(employeeScroll, BorderLayout.CENTER);
        pack();
    }

    public DefaultListModel<Employee> getListModel() {
        return this.listModel;
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();

        if (source == addButton) {
            // !! AddEmployeeDialog frame = new AddEmployeeDialog(new EmployeeFrame());
            AddEmployeeDialog frame = new AddEmployeeDialog(EmployeeFrame.this);
            frame.setVisible(true);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new EmployeeFrame().setVisible(true);
            }
        });
    }

}

@SuppressWarnings("serial")
class AddEmployeeDialog extends JDialog implements ActionListener {
    private JComboBox<String> workerType;
    private JTextField givenNameField;
    private JTextField familyNameField;

    private JButton okButton;
    private JButton cancelButton;

    private EmployeeFrame employeeFrame;

    public AddEmployeeDialog(final EmployeeFrame frame) {
        super(frame, "Add Employee", true);
        setLocationRelativeTo(employeeFrame);
        this.employeeFrame = frame;

        workerType = new JComboBox<String>(Employee.getEmployeeTypes());
        givenNameField = new JTextField(20);
        familyNameField = new JTextField(20);

        Box workerBox = Box.createHorizontalBox();
        workerBox.add(new JLabel("Worker type"));
        workerBox.add(workerType);
        workerBox.add(new JLabel("Start date"));
        Box givenNameBox = Box.createHorizontalBox();
        givenNameBox.add(new JLabel("Given name "));
        givenNameBox.add(givenNameField);

        Box familyNameBox = Box.createHorizontalBox();
        familyNameBox.add(new JLabel("Family name"));
        familyNameBox.add(familyNameField);

        workerType.setSelectedItem(null);

        // Create buttons and add the current class as an ActionListener
        okButton = new JButton("OK");
        okButton.addActionListener(this);
        cancelButton = new JButton("Cancel");
        cancelButton.addActionListener(this);

        Box bottomBox = Box.createHorizontalBox();
        bottomBox.add(Box.createHorizontalGlue());
        bottomBox.add(okButton);
        bottomBox.add(Box.createHorizontalGlue());
        bottomBox.add(cancelButton);
        bottomBox.add(Box.createHorizontalGlue());

        // Lay out the GUI
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        getContentPane().add(workerBox);
        getContentPane().add(givenNameBox);
        getContentPane().add(familyNameBox);
        getContentPane().add(Box.createVerticalStrut(10));
        getContentPane().add(bottomBox);
        pack();
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();
        if (source == okButton) {
            System.out.println("here");
            System.out.println(workerType.getSelectedItem());
            if ("Salaried".equalsIgnoreCase(workerType.getSelectedItem().toString())) {
                Employee employee = new Employee("Salaried", givenNameField.getText(), familyNameField.getText());
                employeeFrame.getListModel().addElement(employee);
            } else {
                Employee employee = new Employee("Hourly", givenNameField.getText(), familyNameField.getText());
                employeeFrame.getListModel().addElement(employee);
            }
        }
        dispose();
    }

}

class Employee {

    private static final String[] EMPLOYEE_TYPES = { "Salaried", "Hourly" };
    private String givenName;
    private String familyName;
    private String type;

    public Employee(String type, String givenName, String familyName) {
        this.type = type;
        this.givenName = givenName;
        this.familyName = familyName;
    }

    public static String[] getEmployeeTypes() {
        return EMPLOYEE_TYPES;
    }

    public String getGivenName() {
        return givenName;
    }

    public String getFamilyName() {
        return familyName;
    }

    public String getType() {
        return type;
    }

    @Override
    public String toString() {
        return String.format("Employee: %s, %s %s", type, givenName, familyName);
    }

}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Yesss, thank you so much. That is exactly what I'm looking for. – sambebop Dec 01 '15 at 22:37
  • I'm sorry for the previous misunderstanding, I am still very new to this and still learning. Thanks again for the help. – sambebop Dec 01 '15 at 22:39
  • @sambebop: you're welcome, in the future, please paste less code, and just pertinent code. You should have created a small program, one that has a small Employee class that just has names and type fields, a JList, a button, and maybe a small JDialog, just enough to demonstrate your problem. I had to make many changes to your code to get it to work, including creating my own Employee class, and the onus of effort should be yours, since you're asking the questions. Let me show you what I mean in a few minutes. – Hovercraft Full Of Eels Dec 01 '15 at 22:39
  • @sambebop: Please see the changes that I made to your code. The program has the imports, all the classes are in one file with the file having the main method being public, and any buttons or functionality or attempt to prettify it that are not essential are deleted. And it includes a rudimentary Employee class. – Hovercraft Full Of Eels Dec 01 '15 at 22:48
  • Wow, thank you for taking the time to help me better understand this. It really means a lot. – sambebop Dec 01 '15 at 22:53