How to change the jtable data by clicking the search button?
I have here a not so short working code. I need help in my search button. If I type in the textfield and click the search button the table data should be changed to what is written in the textfield . If it doesn’t searched anything then the table should be blank. What I can’t make it work here is the showing of the new data into the table. Should I remove the first data and then repaint() ? Or is there a better solution for that?
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; public class TableSearch < JFrame Card = new JFrame(); static JTable table; JTabbedPane card_tab = new JTabbedPane(); // FOR TAB JPanel buttonpanel = new JPanel(); // FOR BUTTON BELOW FlowLayout flow = new FlowLayout(FlowLayout.LEFT); Border etch = BorderFactory.createEtchedBorder(Color.white, Color.gray); Border margin = new EmptyBorder(10, 10, 10, 10); JTextField text; public TableSearch() throws SQLException, IOException < Card.setVisible(true); Card.setSize(821, 421); Card.setTitle("File Maintenance"); Card.setResizable(false); final Toolkit toolkit = Toolkit.getDefaultToolkit(); Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); int x = (int) ((dimension.getWidth() - Card.getWidth()) / 2); int y = (int) ((dimension.getHeight() - Card.getHeight()) / 2); Card.setLocation(x, y); Card.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); JPanel container = new JPanel(); container.setLayout(new BorderLayout()); container.setBackground(new Color(0, 128, 0)); //container.setBorder(margin); JPanel labelpanel = new JPanel(); labelpanel.setLayout(flow); labelpanel.setBackground(new Color(0, 128, 0)); JLabel label_1 = new JLabel("Description:"); label_1.setFont(new Font("Calibri", Font.BOLD, 20)); label_1.setForeground(Color.YELLOW); labelpanel.add(label_1); text = new JTextField(); text.setPreferredSize(new Dimension(200, 20)); labelpanel.add(text); JButton btnsearch = new JButton("Search"); btnsearch.setPreferredSize(new Dimension(90, 20)); btnsearch.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent arg0) < String search = text.getText(); System.out.println(search); //What should I put here to change the table data. >>); labelpanel.add(btnsearch); JPanel jp1 = new JPanel(); jp1.setBackground(new Color(0, 128, 0)); //jp1.setBorder(new CompoundBorder(etch,margin)); jp1.setLayout(new BorderLayout()); table = new JTable(new TableModel()); JScrollPane scrollPane = new JScrollPane(table); table.setFillsViewportHeight(true); JTableHeader header = table.getTableHeader(); header.setBackground(new Color(224, 223, 227)); header.setFont(new Font("Calibri", Font.BOLD, 20)); table.setRowHeight(25); jp1.add(scrollPane); Card.add(container); container.add(labelpanel, BorderLayout.PAGE_START); container.add(jp1, BorderLayout.CENTER); > public static class TableModel extends DefaultTableModel < public TableModel() < super(new Object[], 0); for (int index = 0; index < 4; index++) < addRow(new Object[]); > > @Override public boolean isCellEditable(int rowIndex, int columnIndex) < return false; >> public static void main(String[] args) < //Use the event dispatch thread for Swing components EventQueue.invokeLater(new Runnable() < @Override public void run() < try < new TableSearch(); >catch (SQLException ex) < Logger.getLogger(TableSearch.class.getName()) .log(Level.SEVERE, null, ex); >catch (IOException ex) < Logger.getLogger(TableSearch.class.getName()) .log(Level.SEVERE, null, ex); >> >); > >
Searching for a Value in a HashMap
Now, if I want to search for «Barry» in the HashMap and get the key which is the most recent (in this case Dec 26th), how would I go about doing that? The .values() method doesn’t seem to work as each key has an ArrayList instead of just one element.
I am fairly new to Java. So, i am not exactly sure how to use an iterator here for this. Can you give me some pointers on that?
3 Answers 3
In java 8 you could use something like this:
Optional>> first = map .entrySet() .stream() .filter(entry -> entry.getValue().contains("Barry")) .sorted(Map.Entry.comparingByKey()) .findFirst();
This get all the entries from the map, filters them based on the value, sort them based on keys and get the first one, if any. You can then use first.ifPresent() method to do whatever you want with the first entry, here i just printing them to the console:
Maybe this is NOT the most efficient algorithm but sure it works
Update 1: To sort dates from latest to earliest, use this:
sorted(Map.Entry.>comparingByKey().reversed())
Update 2: As Andreas said, you can use max instead of sorted which has better asymptotic behavior. In fact, since you just want the latest item, there is no need for sorting entries in order to get it:
Optional>> found = map .entrySet() .stream() .filter(entry -> entry.getValue().contains("Barry")) .max(Map.Entry.comparingByKey());
A Map
Wouldn’t max(comparator) perform much better than sorted(comparator).findFirst() ? Fewer comparisons: n — 1 vs. n * log(n) (probably).
Use the map’s Entry Set . For example:
HashMap> map = new HashMap>(); ArrayList list1 = new ArrayList(); ArrayList list2 = new ArrayList(); list1.add("One"); list1.add("Two"); list1.add("Three"); list2.add("Cat"); list2.add("Dog"); list2.add("Fish"); map.put("Numbers", list1); map.put("Animals", list2); for(Map.Entry> entry : map.entrySet())
Output: Found Cat in Animals
Essentially, what we are doing is iterating over the map’s Entry Set , checking if each value (which we specified is an ArrayList ) contains the String we are looking for, and if it does, we print out the key of the current Entry . (Which, in your case, would be your LocalDate .)
Since you want to find the key while searching for a value, you need to use entrySet() .
Given that your keys are dates, and hence have a natural order, and you want latest matching date, you have 3 choices:
- Keep the HashMap , search entire list, and remember largest key value.
- Change to TreeMap , search backwards using descendingMap() , and stop on first hit.
- Change to reverse-order TreeMap , search, and stop on first hit.
If your list is huge and/or you do the search a lot, a TreeMap is preferable, for performance reasons.
Since it is unclear whether LocalDate is from Java 8 or from Joda-Time, the following code uses compareTo , which is implemented by both. Code doesn’t use Java 8 specific features.
// HashMap HashMap> map = new HashMap<>(); . LocalDate matchedKey = null; for (Entry> entry : map.entrySet()) if (entry.getValue().contains(valueToFind)) if (matchedKey == null || entry.getKey().compareTo(matchedKey) > 0) matchedKey = entry.getKey();
// TreeMap (descending search) TreeMap> map = new TreeMap<>(); . LocalDate matchedKey = null; for (Entry> entry : map.descendingMap().entrySet()) if (entry.getValue().contains(valueToFind))
// TreeMap (reverse-order) TreeMap> map = new TreeMap<>(Collections.reverseOrder()); // or Comparator.reverseOrder() in Java 8 . LocalDate matchedKey = null; for (Entry> entry : map.entrySet()) if (entry.getValue().contains(valueToFind))
Of course, in Java 8, these can also be done using streams and Lambdas.
Searching an ArrayList to change object’s value
I’ve made an ArrayList of players that I want to search through to change the amount they have paid. I want to be able to enter in their ID , then be able to change their amount paid just for that player . I am also writing it to a CSV file but I am not sure how to update that file with the new value. I’m not sure about how to go about doing this. What I want to do is just update a value in the ArrayList for a specific player based on player input on the registration ID , then I want to update that value in the file. Here are my 3 classes that I have made: SquashPlayer
package squashapplication; import java.util.Scanner; /** * * @author Evan */ public class SquashPlayer < private static int maxRegistrationId; private int id; private String name; private String parentName; private String phoneNumber; private String email; private int amountPaid; public SquashPlayer() < >public SquashPlayer(boolean getFromUser) < System.out.println("Enter Full Name:"); this.name = FileUtility.getInput().nextLine(); System.out.println("Enter Parents name:"); this.parentName = FileUtility.getInput().nextLine(); System.out.println("Enter phone number:"); this.phoneNumber = FileUtility.getInput().nextLine(); System.out.println("Enter e-mail:"); this.email = FileUtility.getInput().nextLine(); System.out.println("Enter amount paid:"); this.amountPaid = FileUtility.getInput().nextInt(); FileUtility.getInput().nextLine(); this.id = ++ maxRegistrationId; >public SquashPlayer(int id, String name, int amountPaid , String phoneNumber, String parentName , String email ) < this.id = id; this.amountPaid = amountPaid; this.name = name; this.parentName = parentName; this.email = email; this.phoneNumber = phoneNumber; >public SquashPlayer(String[] parts) < this(Integer.parseInt(parts[0]), parts[1], Integer.parseInt(parts[2]), parts[3],parts[4], parts[5]); if (Integer.parseInt(parts[0]) >maxRegistrationId) < maxRegistrationId = Integer.parseInt(parts[0]); >> public SquashPlayer(String csvValues) < this(csvValues.split(",")); >public String getCSV() < return id + "," + name + "," + amountPaid + "," + phoneNumber + "," + email + "," + parentName; >public String getCSV(boolean withLineFeed)< if(withLineFeed)< return getCSV()+System.lineSeparator(); >else < return getCSV(); >> public String getName() < return name; >public void setName(String name) < this.name = name; >public String getParentName() < return parentName; >public void setParentName(String parentName) < this.parentName = parentName; >public String getPhoneNumber() < return phoneNumber; >public void setPhoneNumber(String phoneNumber) < this.phoneNumber = phoneNumber; >public String getEmail() < return email; >public void setEmail(String email) < this.email = email; >public int getAmountPaid() < return amountPaid; >public void setAmountPaid(int amountPaid) < this.amountPaid = amountPaid; >public int getId() < return id; >public void setId(int id) < this.id = id; >@Override public String toString()
package squashapplication; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; public class SquashMain < public static String MENU = "Options:\nA) Add player\nS) Show players\n G) Update Amount Paid\nX) Exit"; public static String FILE_NAME = "c:\\cis2232\\players.csv"; public static void main(String[] args) throws IOException < Files.createDirectories(Paths.get("/cis2232")); ArrayListtheList = new ArrayList(); loadPlayers(theList); String choice = ""; do < System.out.println(MENU); choice = FileUtility.getInput().nextLine().toUpperCase(); switch(choice)< case "A": SquashPlayer player = new SquashPlayer(true); theList.add(player); BufferedWriter bw = null; FileWriter fw = null; try < fw = new FileWriter(FILE_NAME, true); bw = new BufferedWriter(fw); bw.write(player.getCSV(true)); System.out.println("Done"); >catch (IOException e) < e.printStackTrace(); >finally < try < if (bw != null) < bw.close(); >if (fw != null) < fw.close(); >> catch (IOException ex) < ex.printStackTrace(); >> break; case "S": System.out.println("Here are the players"); for (SquashPlayer SquashPlayer : theList) < System.out.println(SquashPlayer); >break; case "G": case "X": System.out.println("Goodbye"); break; default: System.out.println("Invalid option"); break; > >while (!choice.equalsIgnoreCase("x")); > public static void loadPlayers(ArrayList squash) < System.out.println("Loading players from the list!"); int counter = 0; try< ArrayListtester = (ArrayList) Files.readAllLines(Paths.get(FILE_NAME)); for(String current:tester) < System.out.println("Loading: "+current); SquashPlayer temp = new SquashPlayer(current); squash.add(temp); counter++; >>catch(IOException ex) < System.out.println("Error loading players from file."); System.out.println(ex.getMessage()); >System.out.println("Loaded players from file: "+ counter + " players"); >
package squashapplication; import java.util.Scanner; public class FileUtility
How to implement the search functionality of a JTable in Java?
A JTable is a subclass of JComponent for displaying complex data structures. A JTable component can follow the Model View Controller (MVC) design pattern for displaying the data in rows and columns. A JTable can generate TableModelListener, TableColumnModelListener, ListSelectionListener, CellEditorListener, RowSorterListener interfaces. We can implement the search functionality of a JTable by input a string in the JTextField, it can search for a string available in a JTable. If the string matches it can only display the corresponding value in a JTable. We can use the DocumentListener interface of a JTextField to implement it.
Example
import java.awt.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; public class JTableSearchTest extends JFrame < private JTextField jtf; private JLabel searchLbl; private TableModel model; private JTable table; private TableRowSorter sorter; private JScrollPane jsp; public JTableSearchTest() < setTitle("JTableSearch Test"); jtf = new JTextField(15); searchLbl = new JLabel("Search"); String[] columnNames = ; Object[][] rowData = ,,,,,>; model = new DefaultTableModel(rowData, columnNames); sorter = new TableRowSorter<>(model); table = new JTable(model); table.setRowSorter(sorter); setLayout(new FlowLayout(FlowLayout.CENTER)); jsp = new JScrollPane(table); add(searchLbl); add(jtf); add(jsp); jtf.getDocument().addDocumentListener(new DocumentListener() < @Override public void insertUpdate(DocumentEvent e) < search(jtf.getText()); >@Override public void removeUpdate(DocumentEvent e) < search(jtf.getText()); >@Override public void changedUpdate(DocumentEvent e) < search(jtf.getText()); >public void search(String str) < if (str.length() == 0) < sorter.setRowFilter(null); >else < sorter.setRowFilter(RowFilter.regexFilter(str)); >> >); setSize(475, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); setLocationRelativeTo(null); setResizable(false); setVisible(true); > public static void main(String[] args) < new JTableSearchTest(); >>