Hot questions for Using JTextField in jlist

Question:

Working on a GUI that is for allowing Customers to register their information on 1 GUI (Button click to add new customer) whereby after clicking the add button to register their information it will collect up all their data (forename, surname, address Line 1/2, city & postcode) and then upload it onto a JList in the previous GUI in which it displays the customer's first & last name. From which a user can then select that particular customer and click to update the customer's details in an new GUI.

The problem I'm having is trying to figure out how I can pass all the customer's data from the text-fields in the 2nd GUI and transfer them into the JList in the 1st GUI with only the first & last name being displayed. The 2nd problem I'm also facing is how to then open up another GUI which will then reverse the process when that particular customer has been selected so that changes can be made to their details.

In my Person class in the data-model package I have got the method getFullName which goes as follows:

public String getFullName()
{
    String result = this.forename + " " + this.surname;
    return result;
}

Is does anyone know how or could show me how I would be able to apply a solution to these problems?

I have tried experiementing with the getFullName method within the 2nd GUI upon pressing btnAdd, as shown below:

public void addItem()
{
    String result = this.forename + " " + this.surname;
    return result;
}

But alas I have had no luck.


Answer:

Regarding your questions:

The problem I'm having is trying to figure out how I can pass all the customer's data from the text-fields in the 2nd GUI and transfer them into the JList in the 1st GUI...

There are usually two problems in this situation --

  1. How to get the information held by the fields of add new customer dialog window (and yes, this should be a dialog window of some form, either a JDialog or a JOptionPane) into the parent window object, and
  2. How to be notified exactly when this transfer of information should take place, and this is usually the more problematic of the two.

Again the first issue is usually easy to solve, since it is nothing more than a specific version of the more general problem of how to pass information between two classes. The most simple way to solve it is to have the parent window class call getter methods in the dialog window class to extract its state. For instance, the dialog window could have public getter methods for the data held in each JTextField, which the calling parent window could call, or the dialog class could have a getCustomer() method within which it gathers all the information held by its input fields, creates a Customer object, and then returns that object.

Perhaps a better and more robust way of transferring your data is to structure your program as a Model-View-Control or MVC type program, have your add new customer dialog window update the model when its submit button is pressed, and have the parent main window be notified by the model that its data has been changed, and so it knows that it must update its view of the data. This may be overkill for your program, and so I am not going to push this recommendation at this time, but in the future, when you are creating larger more complex programs, this is really what you will want to be doing since it will more easily allow your program's classes to have high cohesion (code that deals with the same things are close together) and low coupling (code that deals with unlike things are not tightly bound which decreases code complexity), making it much easier to debug and improve your program.

Again, the 2nd issue is more difficult to solve. If the dialog window is to close after obtaining and submitting the information that constitutes one customer, than the easiest solution to this is to make the new customer dialog window a modal JDialog or a JOptionPane (which in really is nothing more than a specialized modal JDialog). Why this helps is that Swing has a special mechanism for modal dialogs where it freezes code flow in the calling window starting immediately after setting the dialog visible. And so the calling code will always know when the dialog is no longer visible since its code's program flow will resume only when the dialog isn't visible. So you would want to extract the dialog window's data in the lines immediately following the one that sets the dialog or JOptionPane visible. And before you discard JOptionPanes as being too simplistic, understand that their second parameter, the one of type Object can take any Swing GUI component as a parameter, including a JPanel that holds a very large and complex GUI, making these tools extremely useful.

If the second dialog window will not be closed on the submission of a Customer and is to be left open, for instance if you want to leave it open so that the user can enter multiple Customers, then you'll likely want it to be a non-modal JDialog and will need to set up some kind of notification scheme so that the calling code will be notified when the user has submitted a Customer. One possible way is to allow the calling class to add an ActionListener to the dialog's submit button by giving the dialog class a public addActionListener(....) method. Another is to use Swing's PropertyChangeSupport and have the calling class add a PropertyChangeListener to the add customer dialog, and thus be notified of significant changes to its properties (i.e., that the submit button has been changed, or that a new Customer has been created). If you use an MVC design for your program, then the notification will be from the model to the view. In other words, the dialog will create the new Customer, the submit button will have the Control add the Customer to the Model, and the main GUI's Model listeners will be notified of the newly created object and will display it.


... how I can pass all the customer's data from the text-fields in the 2nd GUI and transfer them into the JList in the 1st GUI with only the first & last name being displayed

Your JList should be a JList<Customer> so that it holds a collection of complete Customer objects. You can easily change how the JList displays its data by overriding the Customer toString() method (not recommended since this method is more for debugging than for end user display), or better by assigning the JList a custom ListCellRenderer (recommended). The Swing JList tutorial will explain how to do this, and you can come back here with your code attempt if you're stuck at this step.


The 2nd problem I'm also facing is how to then open up another GUI which will then reverse the process when that particular customer has been selected so that changes can be made to their details.

This would be solved in largely the same way as above, except rather than creating a new Customer and adding it to the collection displayed by the JList, you would replace one Customer in the JList with the edited one.

For more detailed help, consider creating and posting a Minimal, Complete, and Verifiable Example Program. We don't want to see your whole program, but rather you should condense your code into the smallest bit that still compiles, has no extra code that's not relevant to your problem, but still demonstrates your problem.

Question:

i am trying to make an application that sends a number of string added by the user to my SQL server. however when i try to add an string to my jlist from jtextfield it gets added twice..

here is the thing

user adds a name to jtextfield . when he hits the + button it is send to jlist

public void addBrand() {

    int index = BrandList.getSelectedIndex(); // get selected index
    if (index == -1) { // no selection, so insert at beginning
        index = 0;
    } 
                else { // add after the selected item
        index++;
    }

    model.insertElementAt(BrandLbl.getText(), index);

    BrandLbl.setText(null);


}

all fine here i see one item added to my jlist

when the user decides the list is complete he hits the "next" button and the sendArraytoDB(JList list) method is called

public static void sendArraytoDB(JList<String> list){
        Connection con = null;
        PreparedStatement stm = null;
        String updQuery = "insert into brand_names (name) values (?)";

        try{
        con = DB.getConnection();
        //con.setAutoCommit(false);
        int x =1;
       stm = con.prepareStatement(updQuery);


        int f = list.getModel().getSize();
        System.out.print(f);
        for (int i=0; i<list.getModel().getSize(); i++){

            String name =list.getModel().getElementAt(i);
            stm.setString(x, name);
            //try{
            stm.executeUpdate();
            //}finally{
            //stm.close();
            //}
        }  
           }catch(SQLException ex){
            System.out.printf("error while sending array to db");
            ex.printStackTrace();
        }finally{
            if (stm != null){

etc etc....

for my bad luck the my databse shows that there are two names sent.. i cant post images so its like

      aa      brand
       1
       2      "the string i sent"

the list has allways one more empty record before my record... trying to see wtf is happening i counted the list size just before i send it

int f = list.getModel().getSize();
        System.out.print(f);

and the answer is 2 ... if i enter 3 records its 6 .. etc...

i narrowed the problem to the model since changing the addBrand() method to

public void addBrand() {
            String all = "xghxc";       
            model.addElement(all);
}

impudently shows two of "xghxc" being added to my list at the same time in front of my very own amazed eyes

i searched google but it doesnt even have a similar problem to mine :(

what i need is a code or an advice or smth to point me to not adding an empty useless record amongst my records

here is my full code for anyone who has the patience and time

MyMain.java

    package tweGraf;

import javax.swing.JFrame;


public class MyMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Gui g = new Gui();
                DB.MakePool();


        g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        g.setSize(1000, 800);
        g.setVisible(true);


    }

}

Gui.java

    package tweGraf;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Gui extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

        private JFrame frameYesNo = new JFrame();

        String message = "all data will perish. are you sure";

    private JPanel Container = new JPanel(); // panels
    private JPanel FirstPanel = new JPanel();
    private JPanel NewSession = new JPanel();
    private JPanel LoadSession = new JPanel();
    private JPanel LoadList = new JPanel();


    private JPanel GraphSub1 = new JPanel();
    private JPanel GraphSub2 = new JPanel();
    private JPanel GraphSub3 = new JPanel();

    private JTabbedPane GraphPanel = new JTabbedPane();

    private JButton NewSessBtn = new JButton(); // buttons
    private JButton LoadSessBtn = new JButton();
    private JButton BackFP = new JButton();
    private JButton plusBrand = new JButton();
    private JButton minusBrand = new JButton();
    private JButton Next = new JButton();

    private JLabel EnterBrandLbl = new JLabel(
            "Please insert brands for analysis "); // Labels

    private JTextField BrandLbl = new JTextField(20); // textfields

    public  DefaultListModel<String> model = new DefaultListModel<String>      
    public JList BrandList = new JList(model); // list
    private JScrollPane MyScrollPane = new JScrollPane(BrandList);

    private CardLayout cardLayout = new CardLayout(); // layouts

    private GridBagLayout MyLayout = new GridBagLayout();
    GridBagConstraints MyConstr = new GridBagConstraints();

    public Gui() {

        super("twegraph");

        NewSessBtn.setText("New Session"); // button configuration
        LoadSessBtn.setText("Load Session");
        BackFP.setText("Back");
        plusBrand.setText("+");
        minusBrand.setText("-");
        Next.setText("Next");

        actionListener al = new actionListener();

        NewSessBtn.addActionListener(al); // add action listeners
        LoadSessBtn.addActionListener(al);
        BackFP.addActionListener(al);
        plusBrand.addActionListener(al);
        minusBrand.addActionListener(al);
        Next.addActionListener(al);
        plusBrand.addActionListener(al);
        minusBrand.addActionListener(al);

        Container.setLayout(cardLayout); // panels to container+

        Container.add(FirstPanel, "FirstPanel");
        Container.add(NewSession, "NewSession");
        Container.add(LoadSession, "LoadSession");
        Container.add(GraphPanel, "GraphPanel");
        Container.add(LoadList, "LoadList");

        FirstPanel.setLayout(MyLayout); // first panel
        MyConstr.gridwidth = 3;
        MyConstr.gridheight = 3;
        MyConstr.weightx = 1.0;
        MyConstr.weighty = 1.0;
        MyConstr.ipadx = 100;
        MyConstr.ipady = 50;
        MyConstr.insets = new Insets(50, 20, 50, 20);

        MyConstr.gridx = 1;
        MyConstr.gridy = 0;
        MyConstr.anchor = GridBagConstraints.NORTH;
        MyLayout.setConstraints(NewSessBtn, MyConstr);
        FirstPanel.add(NewSessBtn);

        MyConstr.gridx = 1;
        MyConstr.gridy = 2;
        MyConstr.anchor = GridBagConstraints.SOUTH;
        MyLayout.setConstraints(LoadSessBtn, MyConstr);
        FirstPanel.add(LoadSessBtn);

        NewSession.setLayout(MyLayout); // New Session panel

        MyConstr.gridwidth = 3;
        MyConstr.gridheight = 3;
        MyConstr.ipadx = 0; // size
        MyConstr.ipady = 0; // size
        MyConstr.gridx = 0;
        MyConstr.gridy = 2;
        MyConstr.insets = new Insets(10, 20, 10, 20);

        MyConstr.anchor = GridBagConstraints.SOUTHWEST;
        MyLayout.setConstraints(BackFP, MyConstr);
        NewSession.add(BackFP);

        MyConstr.anchor = GridBagConstraints.SOUTHEAST;
        MyLayout.setConstraints(Next, MyConstr);
        NewSession.add(Next);

        MyConstr.ipadx = 0; // size
        MyConstr.ipady = 0; // size
        MyConstr.gridx = 0; // place
        MyConstr.gridy = 1; // place
        MyConstr.insets = new Insets(0, 0, 0, 0);

        MyConstr.anchor = GridBagConstraints.PAGE_START;
        MyLayout.setConstraints(EnterBrandLbl, MyConstr);
        NewSession.add(EnterBrandLbl);

        MyConstr.gridx = 0;
        MyConstr.gridy = 1;
        MyConstr.anchor = GridBagConstraints.CENTER;
        MyLayout.setConstraints(BrandLbl, MyConstr);
        NewSession.add(BrandLbl);

        MyConstr.gridx = 2;
        MyConstr.gridy = 1;
        MyConstr.anchor = GridBagConstraints.LAST_LINE_START;
        MyLayout.setConstraints(plusBrand, MyConstr);
        NewSession.add(plusBrand);

        MyConstr.gridx = 2;
        MyConstr.gridy = 1;
        MyConstr.anchor = GridBagConstraints.LAST_LINE_END;
        MyLayout.setConstraints(minusBrand, MyConstr);
        NewSession.add(minusBrand);

        MyConstr.ipadx = 0; // size
        MyConstr.ipady = 0;
        MyConstr.gridx = 0;
        MyConstr.gridy = 1;
        MyConstr.anchor = GridBagConstraints.SOUTH;
        MyLayout.setConstraints(MyScrollPane, MyConstr);
        NewSession.add(MyScrollPane);


        GraphPanel.addTab("overall",GraphSub1);             //Graph panel
        GraphPanel.addTab("tweets/time",GraphSub2);
        GraphPanel.addTab("fame",GraphSub3);



        this.setContentPane(Container);

        cardLayout.show(Container, "FirstPanel");

    }

    public class actionListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {

            JButton src = (JButton) event.getSource();
                        int answer = 0;

                        if (src.equals(NewSessBtn))
                        {
                                answer =       JOptionPane.showConfirmDialog(frameYesNo, message);
                                if (answer == JOptionPane.YES_OPTION) {
                                    cardLayout.show(Container,        "NewSession");
                                    try {
                                        DB.flushData();
                                        } catch (SQLException ex) {
                                        Logger.getLogger(Gui.class.getName()).log(Level.SEVERE, null, ex);
                                        }
                                } else if (answer == JOptionPane.NO_OPTION) {
                                    frameYesNo.dispose();
                                }
                        }   
            if (src.equals(LoadSessBtn)){
                cardLayout.show(Container, "LoadSession");
                        }
            if (src.equals(BackFP)){
                cardLayout.show(Container, "FirstPanel");
                        }
            if (src.equals(Next)){

                cardLayout.show(Container, "GraphPanel");
                                DB.sendArraytoDB(BrandList);

            }

            if (src.equals(plusBrand)){

                addBrand();
                        }           
            if (src.equals(minusBrand))
                        {

                removeBrand();
                        }

        }
    }

    public void addBrand() {

        /*int index = BrandList.getSelectedIndex(); // get selected index
        if (index == -1) { // no selection, so insert at beginning
            index = 0;
        } 
                    else { // add after the selected item
            index++;
        }*/
                String all = "xghxc";
        //model.insertElementAt(BrandLbl.getText(), index);
                model.addElement(all);
        //BrandLbl.setText(null);


    }


    public void removeBrand() {
        int index2 = BrandList.getSelectedIndex();
                if (index2 != -1){
        model.remove(index2);
                }



        int size = model.getSize();

        if (size == 0) {
            minusBrand.setEnabled(false);

        } else {
            //if (index == model.getSize()) {
                //index--;
            //}

        }

    }



}

DB.java

    package tweGraf;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JList;

/**
 *
 * @author cheval
 */
public class DB {

    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
   static final String DB_URL = "jdbc:mysql://localhost:3306/twegrahpdb";



   static final String USER = "root";
   static final String PASS = "Xrt38H0a";

    private static ComboPooledDataSource cdps = new ComboPooledDataSource();
    public static void MakePool(){
        try {
        cdps = new ComboPooledDataSource();
        cdps.setDriverClass(JDBC_DRIVER);
        cdps.setJdbcUrl(DB_URL);
        cdps.setUser(USER);
        cdps.setPassword(PASS);
        cdps.setMaxPoolSize( 50 );
        cdps.setMaxStatements(50);
        }catch(Exception ex){
            System.out.printf("error smth wrong happened");
        }
    }

        public static Connection getConnection() throws SQLException{
            return cdps.getConnection();
        }

        public static void flushData() throws SQLException{
            Statement stm = null;
            Connection con = null;
            try{
            con = DB.getConnection();
            stm = con.createStatement();
            String flushquery1 = "TRUNCATE json_cache";
            String flushquery2 = "TRUNCATE tweets";
            String flushquery3 = "TRUNCATE tweet_mentions";
            String flushquery4 = "TRUNCATE tweet_tags";
            String flushquery5 = "TRUNCATE tweet_urls";
            String flushquery6 = "TRUNCATE users";
            String flushquery7 = "TRUNCATE brand_names";
            stm.executeUpdate(flushquery1);
            stm.executeUpdate(flushquery2);
            stm.executeUpdate(flushquery3);
            stm.executeUpdate(flushquery4);
            stm.executeUpdate(flushquery5);
            stm.executeUpdate(flushquery6);
            stm.executeUpdate(flushquery7);
            }catch (SQLException e) {
                System.out.printf("error executing db clear");
            } finally {
                if (stm != null){
                    try{
                    stm.close();
                    System.out.printf("statement closed successfuly \n");
                    } catch (SQLException e){
                        System.out.printf("error closing statement");
                    }
                }
                if (con != null){
                    try{
                       con.close();
                       System.out.printf("connection closed succesfully \n");
                    } catch (SQLException e){
                        System.out.printf("error closing connection");

                    }
                }
            }

        }

        public static void sendArraytoDB(JList<String> list){
            Connection con = null;
            PreparedStatement stm = null;
            String updQuery = "insert into brand_names (name) values (?)";

            try{
            con = DB.getConnection();
            //con.setAutoCommit(false);
            int x =1;
           stm = con.prepareStatement(updQuery);


            int f = list.getModel().getSize();
            System.out.print(f);
            for (int i=0; i<list.getModel().getSize(); i++){

                String name =list.getModel().getElementAt(i);
                stm.setString(x, name);
                //try{
                stm.executeUpdate();
                //}finally{
                //stm.close();
                //}
            }  
               }catch(SQLException ex){
                System.out.printf("error while sending array to db");
                ex.printStackTrace();
            }finally{
                if (stm != null){

                    try {
                        stm.close();
                    } catch (SQLException ex) {
                        Logger.getLogger(DB.class.getName()).log(Level.SEVERE, null, ex);
                    }

                }
                if (con != null){
                    try {
                        con.close();
                    } catch (SQLException ex) {
                        Logger.getLogger(DB.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }

        }
    }

if you still dont know dont care about my actual problem but STILL see smth wrong regarding my coding style or my techniques plz post it

thanks for your time


Answer:

i narrowed the problem to the model since changing the addBrand() method to...

So this tells me the addBrand() method is called multiple times.

    plusBrand.addActionListener(al);
    minusBrand.addActionListener(al);
    Next.addActionListener(al);
    plusBrand.addActionListener(al);
    minusBrand.addActionListener(al);

As you can see above you add the listener twice to the button.

Question:

Sorry if this is an easy answer or has been answered, but have searched and couldnt find anything. I am currently creating a supermarket checkout line with the products in a DefaultListModel, each product having a name, price, weight and code as shown below

public class Product {
private String name;
private double weight;
private double price;
private int code;

public Product (){
}

public Product (String Name, double kg, double pounds, int id){
name = Name;
weight = kg;
price = pounds;
code = id;

public String toString (){
return name + " - " + "£" + price + "    Product # " + code;

and the products put into a list

public class productList extends DefaultListModel {
public productList (){
    super();
}
public void addProduct (String name, double weight, double price, int code){
super.addElement(new Product(name, weight, price, code));

this has been used in the GUI for the checkout in the code segments as follows

private DefaultListModel defaultMainList = new DefaultListModel();
//other code
currentBasket.setModel(defaultMainList); //currentBasket is name of jlist

    productsList = new productList();

    productsList.addProduct("bananas", 0.5, 0.99, 1);
    productsList.addProduct("apples", 0.8, 1.39, 2);
    //etc etc, other products emitted
    mainCheckoutList.setModel(productsList);
    //unimportant code
addBasketItem = new JButton();
        getContentPane().add(addBasketItem);
        addBasketItem.setText("Add >");
        addBasketItem.setBounds(215, 108, 62, 31);
        addBasketItem.addActionListener(new ActionListener(){
            public void actionPerformed (ActionEvent e){
                    defaultMainList.addElement(productsList.getElementAt(mainCheckoutList.getSelectedIndex()));
                mainTillPrice.setText((defaultMainList.toString()));

this current code adds the item from the jlist on the left (main checkout list, which is my list of available products) to the jlist on the right which is my basket. It also adds the entire string of characters in the right list to the jtextfield called mainTillPrice, i want to know if there is any way just to add the price, eg. for the bananas object add 0.99, and then with subsequent items added add their prices as well to keep a running total. Any help would be appreciated and again sorry for any problems in explanation or code, i am fairly new.


Answer:

Well, I wouldn't be using defaultMainList.toString(). You will need to get the Product which is been added, get the price of the Product and add it to the current tally. This value would then need to be added to the mainTillPrice text field

public void actionPerformed (ActionEvent e){
    Product product = (Product)mainCheckoutList.getSelectedItem();
    defaultMainList.addElement(product);
    runningTally += product.getPrice();
    mainTillPrice.setText(NumberFormat.getCurrencyInstance().format(runningTally));

This will require you to create an instance field called runningTally and assumes you have a method getPrice in your Product

Question:


Answer:

The DefaultListModel is: public class DefaultListModel<E> extends AbstractListModel<E> so what you can do is either create a class like POJO and override toString method to show the Athlete Name and add the object to DefaultListModel otherwise only create the DLM as follows:

DefaultListModel<String> DLM = new DefaultListModel<String>();
for(int i = 0; i < athletes.length; i++)
  DLM.addElement(athletes[i]);
listAthlete.setModel (DLM);

Then on selection of the athlete name you can get the details from appropriate array with the index no of the list item selected.

Question:

import java.awt.GridLayout;
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.JList;

public class PetUI extends JFrame implements ActionListener{
JButton btnAdd = new JButton("Add");
JButton btnCancel = new JButton("Cancel");
JTextField txtbox1 = new JTextField();
JTextField txtbox2 = new JTextField();
public PetUI(){
  super("Pet Shop");
  JPanel panel1 = new JPanel();
  JPanel panel2 = new JPanel();

  //inputs
  panel1.setLayout(new GridLayout(3,4));
  add(panel1,BorderLayout.NORTH);
  panel1.add(new JLabel("Pet Type: "));
  String [] animals = {"Cat","Dog","Rabbit"};
  JComboBox petlist = new JComboBox(animals);
  panel1.add(petlist);
  panel1.add(new JLabel("Breed: "));
  panel1.add(txtbox1);
  panel1.add(new JLabel("Name: "));
  panel1.add(txtbox2);

  //buttons
  add(panel2,BorderLayout.CENTER);
  panel2.add(btnAdd);
  btnAdd.addActionListener(this);
  panel2.add(btnCancel);      

  setVisible(true);
  setSize(300,300);
  setDefaultCloseOperation(EXIT_ON_CLOSE);
 }
 public void actionPerformed(ActionEvent e){

 }
 public static void main(String [] args){
  new PetUI();
 }
}

How do I do this? Output it to a JList. My teacher didn't taught this to us. And I tried to search it online but it didn't worked out. I've been through so many YT tutorials already and it didn't worked out.


Answer:

Welcome to SO. Here is something very basic to get you started:

public class PetUI extends JFrame implements ActionListener{

    JButton btnAdd = new JButton("Add");
    JButton btnCancel = new JButton("Cancel");
    JTextField txtbox1 = new JTextField();
    JTextField txtbox2 = new JTextField();
    JList<String> list;
    DefaultListModel<String> listModel;
    JComboBox<String> petList;

    public PetUI(){

        super("Pet Shop");

        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();

        //inputs
        panel1.setLayout(new GridLayout(3,4));
        add(panel1,BorderLayout.NORTH);
        panel1.add(new JLabel("Pet Type: "));
        String [] animals = {"Cat","Dog","Rabbit"};
        petList = new JComboBox<>(animals);
        panel1.add(petList);
        panel1.add(new JLabel("Breed: "));
        panel1.add(txtbox1);
        panel1.add(new JLabel("Name: "));
        panel1.add(txtbox2);

        //buttons
        add(panel2,BorderLayout.CENTER);
        panel2.add(btnAdd);
        btnAdd.addActionListener(this);
        panel2.add(btnCancel);

        //JList
        listModel = new DefaultListModel<>();

        list = new JList<>(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        list.setVisibleRowCount(-1);

        JPanel panel3 = new JPanel();
        panel3.setLayout(new FlowLayout(FlowLayout.LEFT));
        panel3.add(list);
        add(panel3,BorderLayout.SOUTH);

        setVisible(true);
        setSize(300,300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent e){

        StringBuilder sb = new StringBuilder((String)petList.getSelectedItem());
        sb.append(" ")  //add space
          .append(txtbox1.getText())
          .append(" ")
          .append(txtbox2.getText());

        listModel.addElement(sb.toString());
    }
    public static void main(String [] args){
        new PetUI();
    }
}