Java Swing - 如何使下一个和上一个按钮显示数组中对象的变量?

时间:2023-01-27 15:47:35

everyone. I've made an array of a custom class "Human" to create a "City."
Each human has a randomly generated name and age.
I want to use next and previous buttons to scroll through each human and view their information.
How would I go about doing this?
Here is my source code:

大家。我已经制作了一个自定义类“人类”的阵列来创建一个“城市”。每个人都有一个随机生成的名字和年龄。我想使用下一个和上一个按钮滚动每个人并查看他们的信息。我该怎么做呢?这是我的源代码:

JamiesCity.java:

JamiesCity.java:

package jamiesCity;

import javax.swing.*;

import net.miginfocom.swing.MigLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class JamiesCity {

    public static void main(String[] args) {
        JamiesCity j = new JamiesCity();
        j.createMainGUI();
    }

    City newCity;

    public void createMainGUI(){    
        JFrame startGUI;
        startGUI = new JFrame();
        startGUI.setSize(485, 85);
        startGUI.setLocationRelativeTo(null);
        startGUI.setTitle("Jamie's City");
        startGUI.setLayout(null);
        startGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        startGUI.setResizable(false);

        JButton create;
        create = new JButton("New City");
        create.setBounds(15, 15, 130, 25);
        startGUI.add(create);

        JTextField title;
        title = new JTextField("City Name");
        title.setBounds(155, 15, 305, 25);
        startGUI.add(title);

        create.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                createCity(title.getText());
            }
        });
        startGUI.setVisible(true);
    }

    public void createCity(String name){
        newCity = new City(name);
        dispCityInfo(name, newCity);        
    }

    public void dispCityInfo(String name, City city){
        JFrame dispCity = new JFrame(name);
        dispCity.setLocationRelativeTo(null);
        dispCity.setResizable(false);
        dispCity.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel panel = new JPanel();

        panel.setLayout(new MigLayout("insets 30"));

        JLabel personMarker = new JLabel("-------Person-------");
        JLabel cityName = new JLabel("City Name: ");
        JLabel cityPopulation = new JLabel("City Population: ");
        JLabel personName = new JLabel("Name: ");
        JLabel personAge = new JLabel("Age: ");
        JLabel personGender = new JLabel("Gender: ");

        String theName = new String(city.getFirstNameOfPerson(0) + " " + newCity.getLastNameOfPerson(0));
        String theAge = new String(city.getAgeOfPersonAsString(0));
        String theGender = new String(city.getGenderOfPerson(0));

        JLabel theCityName = new JLabel(city.getCityName());
        JLabel theCityPopulation = new JLabel(city.getPopulationAsString());
        JLabel thePersonName = new JLabel(theName);
        JLabel thePersonAge = new JLabel(theAge);
        JLabel thePersonGender = new JLabel(theGender);

        JButton next = new JButton("Next");
        JButton previous = new JButton("Previous");

        //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        dispCity.add(panel);
        panel.add(cityName);
        panel.add(theCityName, "wrap");
        panel.add(cityPopulation);
        panel.add(theCityPopulation, "wrap");
        panel.add(personMarker, "span 2, align center, wrap");
        panel.add(personName);
        panel.add(thePersonName, "wrap");
        panel.add(personAge);
        panel.add(thePersonAge, "wrap");
        panel.add(personGender);
        panel.add(thePersonGender, "wrap");
        panel.add(next, "cell 0 6 2 1, width 200");
        panel.add(previous, "cell 0 7 2 1, width 200");

        //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        next.addActionListener(new ActionListener() { //show info of next person
            public void actionPerformed(ActionEvent e) {

            }
        });

        previous.addActionListener(new ActionListener() { //show info of previous person
            public void actionPerformed(ActionEvent e) {

            }
        });

        //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        dispCity.pack();
        dispCity.setVisible(true);
    }

}

City.java:

City.java:

package jamiesCity;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class City {

    //Variables

    private String CityName;
    private int population;
    private int popLength;
    public Human[] thePeople;
    private ArrayList<String> maleFirsts = new ArrayList<String>();
    private ArrayList<String> femaleFirsts = new ArrayList<String>();
    private ArrayList<String> lasts = new ArrayList<String>();

    //Constructor

    public City(String cityName){

        this.CityName = cityName;

        Random rand = new Random();
        int randomNum = rand.nextInt((8000000 - 10000) + 1) + 10000;
        this.setPopulation(randomNum);  

        thePeople = new Human[(int) population];

        MaleFirstNames();
        FemaleFirstNames();
        LastNames();

        for(int i = 0; i < thePeople.length; i++){

            String MFirstName = "";
            Random MfirstNames = new Random();
            int MfirstNameRand = MfirstNames.nextInt((maleFirsts.size() - 0) + 0);
            MFirstName = maleFirsts.get(MfirstNameRand);

            String FFirstName = "";
            Random FfirstNames = new Random();
            int FfirstNameRand = FfirstNames.nextInt((maleFirsts.size() - 0) + 0);
            FFirstName = femaleFirsts.get(FfirstNameRand);

            String LastName = "";
            Random LastNameRand = new Random();
            int LastNameRandomNumber = LastNameRand.nextInt((lasts.size() - 0) + 0);
            LastName = lasts.get(LastNameRandomNumber);

            Random AgeRand = new Random();
            int Age = AgeRand.nextInt((101 - 1) + 1);

            if(i < thePeople.length / 2){
                thePeople[i] = new Human(MFirstName, LastName, Age, "Male");
            }
            if(i == thePeople.length / 2){
                thePeople[i] = new Human(FFirstName, LastName, Age, "Female");
            }   
        }
        this.popLength = thePeople.length;
    }

    //Scan CSVs

    private void MaleFirstNames(){
        File maleFirstsCSV = new File("src/jamiesCity/male.firstnames.csv");
        try {
            Scanner maleFirstNames = new Scanner(maleFirstsCSV);
            while(maleFirstNames.hasNext()){
                String input = maleFirstNames.next();
                String values[] = input.split(",");
                maleFirsts.add(values[0]);
            }
            maleFirstNames.close();
        } catch (FileNotFoundException e) {
            System.out.println("Cannot Find Male First Names CSV File");
        }
    }

    private void FemaleFirstNames(){
        File maleFirstsCSV = new File("src/jamiesCity/female.firstnames.csv");
        try {
            Scanner femaleFirstNames = new Scanner(maleFirstsCSV);
            while(femaleFirstNames.hasNext()){
                String input = femaleFirstNames.next();
                String values[] = input.split(",");
                femaleFirsts.add(values[0]);
            }
            femaleFirstNames.close();
        } catch (FileNotFoundException e) {
            System.out.println("Cannot Find Female First Names CSV File");
        }
    }

    private void LastNames(){
        File maleFirstsCSV = new File("src/jamiesCity/CSV_Database_of_Last_Names.csv");
        try {
            Scanner lastNames = new Scanner(maleFirstsCSV);
            while(lastNames.hasNext()){
                String input = lastNames.next();
                String values[] = input.split(",");
                lasts.add(values[0]);
            }
            lastNames.close();
        } catch (FileNotFoundException e) {
            System.out.println("Cannot Find Last Names CSV File");
        }
    }

    //Getters and Setters

    public String getFirstNameOfPerson(int HumanCount){
        String name = thePeople[HumanCount].getFirstName();
        return name;
    }
    public String getGenderOfPerson(int HumanCount){
        String gender = thePeople[HumanCount].getGender();
        return gender;
    }
    public String getLastNameOfPerson(int HumanCount){
        String name = thePeople[HumanCount].getLastName();
        return name;
    }
    public int getAgeOfPerson(int HumanCount){
        int age = thePeople[HumanCount].getAge();
        return age;
    }

    public String getAgeOfPersonAsString(int HumanCount){
        StringBuilder age = new StringBuilder();
        age.append(thePeople[HumanCount].getAge());
        String theAge = age.toString();
        return theAge;
    }

    public int getPopLength() {
        return popLength;
    }

    public void setPopLength(int i){
        this.popLength = i;
    }

    public int getPopulation() {
        return population;
    }

    public String getPopulationAsString() {
        StringBuilder builder = new StringBuilder();
        builder.append(population);
        String pop = builder.toString();
        return pop;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    public String getCityName() {
        return CityName;
    }

    public void setCityName(String cityName) {
        CityName = cityName;
    }

    //End of Getters and Setters
}

Human.java:

Human.java:

package jamiesCity;

public class Human {

    private String firstName = "firstName";
    private String lastName = "lastName";
    private int Age = 99;
    private String gender = null;

    public int getAge(){
        return Age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setAge(int age){
        Age = age;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Human(String firstName, String lastName, int Age, String gender){
        this.firstName = firstName;
        this.lastName = lastName;
        this.Age = Age;
        this.gender = gender;
    }

}

Any help would be much appreciated. Thanks :)

任何帮助将非常感激。谢谢 :)

1 个解决方案

#1


5  

Suggestions:

建议:

  • Since this looks to be an assignment, I'm going to avoid giving you code, but rather general suggestions that should hopefully get you started.
  • 由于这看起来像是一项任务,我将避免给你代码,而是一般性的建议,希望能让你开始。
  • Create an int index variable to whatever array or collection holds your Humans -- here it looks to be the thePeople array. Make this index a non-static field.
  • 创建一个int索引变量来保存你的人类的任何数组或集合 - 这里它看起来像thePeople数组。使此索引成为非静态字段。
  • In the next button's ActionListener, advance the index, make sure that it's not the same size or bigger than the array or collection, get the Human for that index, and display it in your GUI.
  • 在下一个按钮的ActionListener中,推进索引,确保它与数组或集合的大小不同或更大,获取该索引的Human,并将其显示在GUI中。
  • Conversely in the previous button, decrement the index, make sure that it's 0 or bigger, and then get the Human for that index, and display it in your GUI.
  • 相反,在上一个按钮中,递减索引,确保它为0或更大,然后获取该索引的Human,并将其显示在GUI中。
  • You will want to decide what you want to happen should the index hit a boundary -- either become less than 0 or equal to your array's length. If you want to cycle the search, then if it gets less than zero, you'll want to assign it to length - 1 or if it gets to length size, then assign it to 0.
  • 如果索引到达边界,您将需要决定要发生什么 - 要么变得小于0,要么等于数组的长度。如果要循环搜索,那么如果它小于零,则需要将其分配给length - 1或者如果它达到length size,则将其分配给0。

Unrelated suggestions:

无关的建议:

  • Avoid null layouts. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
  • 避免使用null布局。虽然null布局和setBounds()看起来像Swing新手一样,是创建复杂GUI的最简单和最好的方法,但是你创建的Swing GUI越多,在使用它们时就会遇到更严重的困难。当GUI调整大小时,它们不会调整组件的大小,它们是增强或维护的皇室女巫,当它们被放置在滚动窗格中时它们完全失败,当它们在所有平台上观看时或者与原始平台不同的屏幕分辨率时它们看起来很糟糕。
  • You will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
  • 您将需要学习和使用Java命名约定。变量名都应以较低的字母开头,而类名以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他代码。

OK I lied and did create something to test concepts:

好吧,我撒谎,并创建了一些东西来测试概念:

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("serial")
public class SimpleCityGui extends JPanel {
    private SimpleCity city = new SimpleCity();
    private SimpleHumanPanel humanPanel = new SimpleHumanPanel();

    public SimpleCityGui() {
        humanPanel.setFocusable(false);
        humanPanel.setBorder(BorderFactory.createTitledBorder("Current Human"));

        JPanel btnPanel = new JPanel();
        btnPanel.add(new JButton(new AddHumanAction("Add")));
        btnPanel.add(new JButton(new NextAction("Next")));
        btnPanel.add(new JButton(new PreviousAction("Previous")));

        setLayout(new BorderLayout());
        add(humanPanel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private class AddHumanAction extends AbstractAction {
        SimpleHumanPanel innerHumanPanel = new SimpleHumanPanel();

        public AddHumanAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            innerHumanPanel.clear();
            Component parentComponent = SimpleCityGui.this;
            SimpleHumanPanel message = innerHumanPanel;
            String title = "Create a Human";
            int optionType = JOptionPane.OK_CANCEL_OPTION;
            int messageType = JOptionPane.PLAIN_MESSAGE;
            int selection = JOptionPane.showConfirmDialog(parentComponent,
                    message, title, optionType, messageType);

            if (selection == JOptionPane.OK_OPTION) {
                city.addHuman(innerHumanPanel.createHuman());
                humanPanel.setHuman(city.getCurrentHuman());
            }
        }
    }

    private class NextAction extends AbstractAction {

        public NextAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            SimpleHuman nextHuman = city.next();
            if (nextHuman != null) {
                humanPanel.setHuman(nextHuman);
            }
        }
    }

    private class PreviousAction extends AbstractAction {

        public PreviousAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            SimpleHuman previousHuman = city.previous();
            if (previousHuman != null) {
                humanPanel.setHuman(previousHuman);
            }
        }
    }

    private static void createAndShowGui() {
        SimpleCityGui mainPanel = new SimpleCityGui();

        JFrame frame = new JFrame("SimpleCityGui");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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

@SuppressWarnings("serial")
class SimpleHumanPanel extends JPanel {
    private static final int COLS = 10;
    private static final Insets INSETS = new Insets(5, 5, 5, 5);
    private JTextField firstNameField = new JTextField(COLS);
    private JTextField lastNameField = new JTextField(COLS);
    private JTextComponent[] textComponents = { firstNameField, lastNameField };
    private SimpleHuman human;

    public SimpleHumanPanel() {
        setLayout(new GridBagLayout());
        add(new JLabel("First Name:"), createGbc(0, 0));
        add(firstNameField, createGbc(1, 0));
        add(new JLabel("Last Name:"), createGbc(0, 1));
        add(lastNameField, createGbc(1, 1));
    }

    @Override
    public void setFocusable(boolean focusable) {
        super.setFocusable(focusable);
        for (JTextComponent jTextComponent : textComponents) {
            jTextComponent.setFocusable(focusable);
        }
    }

    public void setHuman(SimpleHuman human) {
        this.human = human;
        firstNameField.setText(human.getFirstName());
        lastNameField.setText(human.getLastName());
    }

    public SimpleHuman getHuman() {
        return human;
    }

    public void clear() {
        this.human = null;
        for (JTextComponent jTextComponent : textComponents) {
            jTextComponent.setText("");
        }
    }

    public SimpleHuman createHuman() {
        String firstName = firstNameField.getText();
        String lastName = lastNameField.getText();
        human = new SimpleHuman(firstName, lastName);
        return human;
    }

    private static GridBagConstraints createGbc(int x, int y) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.insets = INSETS;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        return gbc;
    }
}

class SimpleCity {
    private List<SimpleHuman> humanList = new ArrayList<>();
    private int humanListIndex = -1; // start with a nonsense value

    public void addHuman(SimpleHuman h) {
        humanList.add(h);
        if (humanListIndex == -1) {
            humanListIndex = 0;
        }
    }

    public SimpleHuman getHuman(int index) {
        return humanList.get(index);
    }

    public SimpleHuman getCurrentHuman() {
        if (humanListIndex == -1) {
            return null;
        }
        return humanList.get(humanListIndex);

    }

    public SimpleHuman next() {
        if (humanListIndex == -1) {
            return null;
        }

        humanListIndex++;
        humanListIndex %= humanList.size(); // set back to 0 if == size
        return humanList.get(humanListIndex);
    }

    public SimpleHuman previous() {
        if (humanListIndex == -1) {
            return null;
        }

        humanListIndex--;
        humanListIndex += humanList.size();
        humanListIndex %= humanList.size();
        return humanList.get(humanListIndex);
    }
}

class SimpleHuman {
    private String firstName;
    private String lastName;

    public SimpleHuman(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((firstName == null) ? 0 : firstName.hashCode());
        result = prime * result
                + ((lastName == null) ? 0 : lastName.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        SimpleHuman other = (SimpleHuman) obj;
        if (firstName == null) {
            if (other.firstName != null)
                return false;
        } else if (!firstName.equals(other.firstName))
            return false;
        if (lastName == null) {
            if (other.lastName != null)
                return false;
        } else if (!lastName.equals(other.lastName))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "SimpleHuman [firstName=" + firstName + ", lastName=" + lastName
                + "]";
    }

}

#1


5  

Suggestions:

建议:

  • Since this looks to be an assignment, I'm going to avoid giving you code, but rather general suggestions that should hopefully get you started.
  • 由于这看起来像是一项任务,我将避免给你代码,而是一般性的建议,希望能让你开始。
  • Create an int index variable to whatever array or collection holds your Humans -- here it looks to be the thePeople array. Make this index a non-static field.
  • 创建一个int索引变量来保存你的人类的任何数组或集合 - 这里它看起来像thePeople数组。使此索引成为非静态字段。
  • In the next button's ActionListener, advance the index, make sure that it's not the same size or bigger than the array or collection, get the Human for that index, and display it in your GUI.
  • 在下一个按钮的ActionListener中,推进索引,确保它与数组或集合的大小不同或更大,获取该索引的Human,并将其显示在GUI中。
  • Conversely in the previous button, decrement the index, make sure that it's 0 or bigger, and then get the Human for that index, and display it in your GUI.
  • 相反,在上一个按钮中,递减索引,确保它为0或更大,然后获取该索引的Human,并将其显示在GUI中。
  • You will want to decide what you want to happen should the index hit a boundary -- either become less than 0 or equal to your array's length. If you want to cycle the search, then if it gets less than zero, you'll want to assign it to length - 1 or if it gets to length size, then assign it to 0.
  • 如果索引到达边界,您将需要决定要发生什么 - 要么变得小于0,要么等于数组的长度。如果要循环搜索,那么如果它小于零,则需要将其分配给length - 1或者如果它达到length size,则将其分配给0。

Unrelated suggestions:

无关的建议:

  • Avoid null layouts. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
  • 避免使用null布局。虽然null布局和setBounds()看起来像Swing新手一样,是创建复杂GUI的最简单和最好的方法,但是你创建的Swing GUI越多,在使用它们时就会遇到更严重的困难。当GUI调整大小时,它们不会调整组件的大小,它们是增强或维护的皇室女巫,当它们被放置在滚动窗格中时它们完全失败,当它们在所有平台上观看时或者与原始平台不同的屏幕分辨率时它们看起来很糟糕。
  • You will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
  • 您将需要学习和使用Java命名约定。变量名都应以较低的字母开头,而类名以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他代码。

OK I lied and did create something to test concepts:

好吧,我撒谎,并创建了一些东西来测试概念:

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("serial")
public class SimpleCityGui extends JPanel {
    private SimpleCity city = new SimpleCity();
    private SimpleHumanPanel humanPanel = new SimpleHumanPanel();

    public SimpleCityGui() {
        humanPanel.setFocusable(false);
        humanPanel.setBorder(BorderFactory.createTitledBorder("Current Human"));

        JPanel btnPanel = new JPanel();
        btnPanel.add(new JButton(new AddHumanAction("Add")));
        btnPanel.add(new JButton(new NextAction("Next")));
        btnPanel.add(new JButton(new PreviousAction("Previous")));

        setLayout(new BorderLayout());
        add(humanPanel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private class AddHumanAction extends AbstractAction {
        SimpleHumanPanel innerHumanPanel = new SimpleHumanPanel();

        public AddHumanAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            innerHumanPanel.clear();
            Component parentComponent = SimpleCityGui.this;
            SimpleHumanPanel message = innerHumanPanel;
            String title = "Create a Human";
            int optionType = JOptionPane.OK_CANCEL_OPTION;
            int messageType = JOptionPane.PLAIN_MESSAGE;
            int selection = JOptionPane.showConfirmDialog(parentComponent,
                    message, title, optionType, messageType);

            if (selection == JOptionPane.OK_OPTION) {
                city.addHuman(innerHumanPanel.createHuman());
                humanPanel.setHuman(city.getCurrentHuman());
            }
        }
    }

    private class NextAction extends AbstractAction {

        public NextAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            SimpleHuman nextHuman = city.next();
            if (nextHuman != null) {
                humanPanel.setHuman(nextHuman);
            }
        }
    }

    private class PreviousAction extends AbstractAction {

        public PreviousAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            SimpleHuman previousHuman = city.previous();
            if (previousHuman != null) {
                humanPanel.setHuman(previousHuman);
            }
        }
    }

    private static void createAndShowGui() {
        SimpleCityGui mainPanel = new SimpleCityGui();

        JFrame frame = new JFrame("SimpleCityGui");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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

@SuppressWarnings("serial")
class SimpleHumanPanel extends JPanel {
    private static final int COLS = 10;
    private static final Insets INSETS = new Insets(5, 5, 5, 5);
    private JTextField firstNameField = new JTextField(COLS);
    private JTextField lastNameField = new JTextField(COLS);
    private JTextComponent[] textComponents = { firstNameField, lastNameField };
    private SimpleHuman human;

    public SimpleHumanPanel() {
        setLayout(new GridBagLayout());
        add(new JLabel("First Name:"), createGbc(0, 0));
        add(firstNameField, createGbc(1, 0));
        add(new JLabel("Last Name:"), createGbc(0, 1));
        add(lastNameField, createGbc(1, 1));
    }

    @Override
    public void setFocusable(boolean focusable) {
        super.setFocusable(focusable);
        for (JTextComponent jTextComponent : textComponents) {
            jTextComponent.setFocusable(focusable);
        }
    }

    public void setHuman(SimpleHuman human) {
        this.human = human;
        firstNameField.setText(human.getFirstName());
        lastNameField.setText(human.getLastName());
    }

    public SimpleHuman getHuman() {
        return human;
    }

    public void clear() {
        this.human = null;
        for (JTextComponent jTextComponent : textComponents) {
            jTextComponent.setText("");
        }
    }

    public SimpleHuman createHuman() {
        String firstName = firstNameField.getText();
        String lastName = lastNameField.getText();
        human = new SimpleHuman(firstName, lastName);
        return human;
    }

    private static GridBagConstraints createGbc(int x, int y) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.insets = INSETS;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        return gbc;
    }
}

class SimpleCity {
    private List<SimpleHuman> humanList = new ArrayList<>();
    private int humanListIndex = -1; // start with a nonsense value

    public void addHuman(SimpleHuman h) {
        humanList.add(h);
        if (humanListIndex == -1) {
            humanListIndex = 0;
        }
    }

    public SimpleHuman getHuman(int index) {
        return humanList.get(index);
    }

    public SimpleHuman getCurrentHuman() {
        if (humanListIndex == -1) {
            return null;
        }
        return humanList.get(humanListIndex);

    }

    public SimpleHuman next() {
        if (humanListIndex == -1) {
            return null;
        }

        humanListIndex++;
        humanListIndex %= humanList.size(); // set back to 0 if == size
        return humanList.get(humanListIndex);
    }

    public SimpleHuman previous() {
        if (humanListIndex == -1) {
            return null;
        }

        humanListIndex--;
        humanListIndex += humanList.size();
        humanListIndex %= humanList.size();
        return humanList.get(humanListIndex);
    }
}

class SimpleHuman {
    private String firstName;
    private String lastName;

    public SimpleHuman(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((firstName == null) ? 0 : firstName.hashCode());
        result = prime * result
                + ((lastName == null) ? 0 : lastName.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        SimpleHuman other = (SimpleHuman) obj;
        if (firstName == null) {
            if (other.firstName != null)
                return false;
        } else if (!firstName.equals(other.firstName))
            return false;
        if (lastName == null) {
            if (other.lastName != null)
                return false;
        } else if (!lastName.equals(other.lastName))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "SimpleHuman [firstName=" + firstName + ", lastName=" + lastName
                + "]";
    }

}