java - How to add jtextfield values to a constructor and an arraylist?

19
2014-04
  • user2994263

    When a user clicks the "add" button, the program is meant to get the values from the jtextfields and then setting it to the constructor. After adding the constructor to an arraylist. Then iterating through the arraylist and printing the values.

    I don't get any errors, but I get null values.

    String title = textfield1.getText();
    String author = textfield2.getText();
    
    Book b = new Book(title, author);
    lib.addBook(b);
    
    System.out.println(b);
    

    I have 3 classes. Book, Library, and Test

    Test

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.table.*;
    import javax.swing.border.*;
    
    public class Test extends JFrame{
    
        private JFrame frame = new JFrame("Book");
        private JPanel panel = new JPanel();
    
        private JLabel label2, label3;
    
        private JTextField textfield1, textfield2;
    
        private JButton button1;
    
        static Library lib = new Library();
    
        void form(){
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
        panel.setLayout(null);
    
    
        label2 = new JLabel("title:");
        label2.setBounds(9, 61, 123, 13);
        panel.add(label2);
    
        label3 = new JLabel("author:");
        label3.setBounds(9, 91, 123, 13);
        panel.add(label3);
    
    
        textfield1 = new JTextField(10);
        textfield1.setBounds(121, 63, 125, 21);
        panel.add(textfield1);
    
        textfield2 = new JTextField(10);
        textfield2.setBounds(121, 93, 125, 21);
        panel.add(textfield2);
    
    
        button1 = new JButton("Add");
        button1.setBounds(351, 226, 125, 21);
        panel.add(button1);
    
    
        frame.add(panel);
        frame.setSize(545,540);
        frame.setVisible(true);
    
    
        button1.addActionListener(new ActionListener(){
        public  void actionPerformed(ActionEvent e){
    
        String title = textfield1.getText();
        String author = textfield2.getText();
    
        Book b = new Book(title, author);
        lib.addBook(b);
    
        System.out.println(b);
    
    
    
        }
        });
    
    
    
    
    
        }
    
        public static void main(String [] args){
    
            Test a = new Test();
            a.form();
            }
    
    
         }
    

    Library

     import java.io.Serializable;
     import java.util.ArrayList;
     import java.util.Iterator;
     import java.util.List;
    
     public class Library{
    
        private List<Book> list = new ArrayList<Book>();
    
        public void addBook(Book b){
            list.add(b);
        }
    
        public String toString() {          
            String total = "\n";            
            Iterator<Book> i = list.iterator();
            while(i.hasNext()){
                Book b = (Book) i.next();
                total = total + b.toString();
            }
            return total;
        }    
    }
    

    Book

     public class Book{
    
        private String title;
        private String author;
    
        public Book(){
    
        title = "";
        author = "";
        }
    
        public Book(String title, String author){           
             title = title;
             author = author;       
          }
    
        public String getTitle(){
            return title;   
        }
        public void setTitle(String title){
            title = title;  
        }
        public String getAuthor(){
            return author;
        }
        public void setAuthor(String author){
            author = author;
        }    
    
        public String toString(){
            return  "Title: " + getTitle() + "\n" + 
                    "Author: " + getAuthor() + "\n";        }   
    }
    
  • Answers
  • Hovercraft Full Of Eels

    This code is bad:

    public Book(String title, String author){
    
    title = title;
    author = author;
    
    }
    

    You're just setting the parameter to itself. Instead use this to set the actual class fields:

    public Book(String title, String author){    
       this.title = title;
       this.author = author;    
    }
    

    The more important lesson to be gained here: continually test your classes and your code in isolation before putting it all together. If you had written a small main method in the Book class to test it out, you'd have found the error.

  • MadProgrammer

    Your main problem lies here...

    public Book(String title, String author){
    
        title = title;
        author = author;
    
    }
    

    You are simply assigning the parameters back them selves, which means the member/instance variables will still be null

    Try using the this keyword to assign the parameters to the member variables

    public Book(String title, String author){
    
        this.title = title;
        this.author = author;
    
    }
    

    Check out Using the this Keyword for more details...


  • Related Question

    java - How to create ArrayList (ArrayList<T>) from array (T[])
  • Ron Tuffin

    I have an array that is initialised like:

    Element[] array = {new Element(1),new Element(2),new Element(3)};
    

    I would like to convert this array into an object of the ArrayList class.

    ArrayList<Element> arraylist = ???;
    

    I am sure I have done this before, but the solution is sitting just at the edge of my memory.


  • Related Answers
  • Tom
    new ArrayList<Element>(Arrays.asList(array))
    
  • rds

    Given:

    Element[] array = new Element[] { new Element(1),new Element(2),new Element(3) };
    

    The simplest answer is to do:

    List<Element> list = Arrays.asList(array);
    

    This will work fine. But some caveats:

    1. The list returned from asList has fixed size. So, if you want to be able to add or remove elements from the returned list in your code, you'll need to wrap it in a new ArrayList. Otherwise you'll get an UnsupportedOperationException.
    2. The list returned from asList() is backed by the original array. If you modify the original array, the list will be modified as well. This may be surprising.
  • Tim Büthe

    Since this question is pretty old, it suprises me that nobody suggested the simplest form yet:

    List<Element> arraylist = Arrays.asList(new Element(1),new Element(2),new Element(3));
    

    As of Java 5, Arrays.asList() takes a varargs parameter and you don't have to construct the array explicit.

  • Bill the Lizard
    new ArrayList<T>(Arrays.asList(myArray));
    
  • haylem

    (old thread, but just 2 cents as none mention Guava or other libs and some other details)

    If You Can, Use Guava

    It's worth pointing out the Guava way, which greatly simplifies these shenanigans:

    Usage

    For an Immutable List

    Use the ImmutableList class and its of() and copyOf() factory methods (elements can't be null):

    List<String> il = ImmutableList.of("string", "elements");  // from varargs
    List<String> il = ImmutableList.copyOf(aStringArray);      // from array
    

    For A Mutable List

    Use the Lists class and its newArrayList() factory methods:

    List<String> l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
    List<String> l2 = Lists.newArrayList(aStringArray);               // from array
    List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs
    

    Please also note the similar methods for other data structures in other classes, for instance in Sets.

    Why Guava?

    The main attraction could be to reduce the clutter due to generics for type-safety, as the use of the Guava factory methods allow the types to be inferred most of the time. However, this argument holds less water since Java 7 arrived with the new diamond operator.

    But it's not the only reason (and Java 7 isn't everywhere yet): the shorthand syntax is also very handy, and the methods initializers, as seen above, allow to write more expressive code. You do in one Guava call what takes 2 with the current Java Collections.


    If You Can't...

    For an Immutable List

    Use the JDK's Arrays class and its asList() factory method, wrapped with a Collections.unmodifiableList():

    List<String> l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
    List<String> l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));
    

    Note that the returned type for asList() is a List using a concrete ArrayList implementation, but it is NOT java.util.ArrayList. It's an inner type, which emulates an ArrayList but actually directly references the passed array and makes it "write through" (modifications are reflected in the array).

    It forbids modifications through some of the List API's methods by way of simply extending an AbstractList (so, adding or removing elements is unsupported), however it allows calls to set() to override elements. Thus this list isn't truly immutable and a call to asList() should be wrapped with Collections.unmodifiableList().

    See the next step if you need a mutable list.

    For a Mutable List

    Same as above, but wrapped with an actual java.util.ArrayList:

    List<String> l1  = new ArrayList<String>(Arrays.asList(array));    // Java 1.5 to 1.6
    List<String> l1b = new ArrayList<>(Arrays.asList(array));          // Java 1.7+
    List<String> l2  = new ArrayList<String>(Arrays.asList("a", "b")); // Java 1.5 to 1.6
    List<String> l2b = new ArrayList<>(Arrays.asList("a", "b"));       // Java 1.7+
    

    For Educational Purposes: The Good ol' Manual Way

    // for Java 1.5+
    static <T> List<T> arrayToList(final T[] array) {
      final List<T> l = new ArrayList<T>(array.length);
    
      for (final T s : array) {
        l.add(s);
      }
      return (l);
    }
    
    // for Java < 1.5 (no generics, no compile-time type-safety, boo!)
    static List arrayToList(final Object[] array) {
      final List l = new ArrayList(array.length);
    
      for (int i = 0; i < array.length; i++) {
        l.add(array[i]);
      }
      return (l);
    }
    
  • Peter Tseng

    Another way (although essentially equivalent to the new ArrayList(Arrays.asList(array)) solution performance-wise:

    Collections.addAll(arraylist, array);
    
  • Kip

    You probably just need a List, not an ArrayList. In that case you can just do:

    List<Element> arraylist = Arrays.asList(array);
    
  • Nicolas Zozol

    If you use :

    new ArrayList<T>(Arrays.asList(myArray));
    

    you may create and fill two lists ! Filling twice a big list is exactly what you don't want to do because it will create another Object[] array each time the capacity needs to be extended.

    Fortunately the JDK implementation is fast and Arrays.asList(a[]) is very well done. It create a kind of ArrayList named Arrays.ArrayList where the Object[] data points directly to the array.

    // in Arrays
    @SafeVarargs
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
    //still in Arrays, creating a private unseen class
    private static class ArrayList<E>
    
            private final E[] a;    
            ArrayList(E[] array) {
                a = array; // you point to the previous array
            }
        ....
    }
    

    The dangerous side is that if you change the initial array, you change the List ! Are you sure you want that ? Maybe yes, maybe not.

    If not, the most understandable way is to do this :

    ArrayList<Element> list = new ArrayList<Element>(myArray.length); // you know the initial capacity
    for (Element element : myArray){
     list.add(element);
    }
    

    Don't use Collections, Arrays, or Guava. I love to use it, but if it don't fit, don't use it. Write another inelegant line instead.

    Well... still use and learn Guava if you can.

  • Bohdan
    // Guava
    import com.google.common.collect.ListsLists
    ...
    List<String> list = Lists.newArrayList(aStringArray); 
    
  • TwoThe

    There is another option if your goal is to generate a fixed list at runtime, which is as simple as it is effective:

    static final ArrayList<Element> myList = generateMyList();
    
    private static ArrayList<Element> generateMyList() {
      final ArrayList<Element> result = new ArrayList<>();
      result.add(new Element(1));
      result.add(new Element(2));
      result.add(new Element(3));
      result.add(new Element(4));
      return result;
    }
    


    The benefit of using this pattern is, that the list is for once generated very intuitively and therefore is very easy to modify even with large lists or complex initialization, while on the other hand always contains the same Elements on every actual run of the program (unless you change it at a later point of course).