I'm trying to fill my list selection listener method with code, but I don't know how to approach it. Essentially, I would like for the method to fill multiple text fields when an item is selected from the JList.
My JList looks like this:
private JList <String> contactList;
private DefaultListModel<String> model;
//Textfields
comboBookType = new JComboBox(BookType.values());
nameText = new JTextField("", 17);
authorText = new JTextField("", 17);
genreText = new JTextField ("", 17);
comboCategory = new JComboBox (readCategory());
//initialize defaultlistmodel and jlist
model = new DefaultListModel <String>();
bookList = new JList (model);
bookList.setVisibleRowCount(10);
bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
bookList.setFixedCellHeight (20);
bookList.setFixedCellWidth (130);
bookList.setBorder (BorderFactory.createLineBorder(Color.BLACK,1));
JPanel left = new JPanel(new BorderLayout());
left.add (new JScrollPane(bookList), BorderLayout.NORTH);
bookList.addListSelectionListener (new ListSelection());
//populating Jlist
class openFileListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
book.getBooks();
for (String name : addressBook.getBooks())
{
model.addElement(name);
}
}
}
//the getBooks() method in my Library class
public ArrayList<String> getBooks ()
{
File file;
Scanner input;
BookType type;
ArrayList<String> books;
ArrayList<String> names = new ArrayList<String>();
try
{
file = new File ("Books.txt");
input = new Scanner (file);
while (input.hasNext())
{
String line = input.nextLine ( );
String [] book = line.split(",");
type = BookType.valueOf(info[0]);
String name = book[1];
b = new Book (type, book[1], book[2], book[3], book[4], info[5]);
list.add (b);
information.add (name);
numOfBooks++;
}
input.close ( );
}
catch (FileNotFoundException e)
{
JOptionPane.showMessageDialog (null, "File not found");
}
return information;
}
Here's what I have so far in my list selection listener:
private class ListSelection implements ListSelectionListener
{
public void valueChanged (ListSelectionEvent e)
{
book.getInfo ( );
int index = bookList.getSelectedIndex ( );
}
//getInfo() method in Library class
public ArrayList<Book> getInfo ()
{
File file;
Scanner input;
BookType type;
ArrayList<String> book;
try
{
file = new File ("Book.txt");
input = new Scanner (file);
while (input.hasNext())
{
String line = input.nextLine ( );
String [] info = line.split(",");
type = BookType.valueOf(info[0]);
String name = info[1];
Book b = new Contact (type, info[1], info[2], info[3], info[4],info[5]);
list.add (b);
}
input.close ( );
}
catch (FileNotFoundException e)
{
JOptionPane.showMessageDialog (null, "File not found");
}
return list;
It's not much, but I have no ideas on where to go from here. I know I have to utilize the index that I got from from getSelectedIndex but I don't know how, please help, thank you.
I know I have to utilize the index that I got from from getSelectedIndex but I don't know how
You would use the index to get the selection item from the ListModel:
String book = model.getElementAt(index);
Or the easier approach is to get the element from the JList using the getSelectedValue() method:
private class ListSelection implements ListSelectionListener
{
public void valueChanged (ListSelectionEvent e)
{
if (e.getValueIsAdjusting()) return;
//book.getInfo ( );
//int index = bookList.getSelectedIndex ( );
String book = bookList.getSelectedValue();
}
}
Now the problem you have is finding the information about the book. You are creating Book objects and adding them to an ArrayList. So now you need to create a loop to look at all entries in the ArrayList. Something like:
ArrayList<Book> bookInfo = getInfo();
for (Book book: bookInfo)
{
if (book.equals(book.getTitle())
{
authorTextField.setText( book.getAuthor());
// ... for the rest of the text fields
return;
}
}
Note a better design would be to read the book info into your class when the class is constructed. This way to don't read the data from the text file every time a selection is made in the JList.
Related
As a part of my assignment I had to store objects of an array in a flat-file and retrieve them when certain criteria was met. I can save the objects fine but when retrieving them I have an issue with getting more than one value, I understand what is going wrong but I am struggling to find a solution. Here is the concept of whats happening.
Button no 10,A (R1S10 in the code)is my testing button, When I click it it creates an event that I will show below.
Click event for button 10A -
private void R1S10ActionPerformed(java.awt.event.ActionEvent evt) {
seats.add(seat1);
if (R1S10.getBackground().equals(Color.red) &&(IsSeatBooked().equals("true"))){
Component frame = null;
JOptionPane.showMessageDialog(frame, "Seat UnBooked");
seat1.setBooked("false");
seat1.setName("");
R1S10.setBackground(Color.yellow);
try {
reader();
writer();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
else{
Component frame = null;
String name = JOptionPane.showInputDialog(frame, "Please enter name of Customer booking");
if (name.isEmpty()) {
JOptionPane.showMessageDialog(frame, "No value entered");
} else if (name != null) {
seat1.setName(name);
seat1.setBooked("true");
R1S10.setBackground(Color.red);
JOptionPane.showMessageDialog(frame, "Your Booking has been placed");
try {
writer();
reader();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Followed by the screen below -
Outcome -
And when the button is pressed again -
I am using three methods in this SeatingPlan.java - writer(),reader() and IsSeatBooked().
SeatingPlan -
public class SeatingPlan extends javax.swing.JFrame {
/**
* Creates new form SeatingPlan
*/
String seatNo, name, bookedSeat;
FileWriter fileWriter = null;
List<Seat> seats = new ArrayList<Seat>();
//Seat Object Declaration
Seat seat1 = new Seat("R1S10","","false");
Seat seat2 = new Seat("R1S9", "", "false");
String fileName = "seat.csv";
writer -
public void writer() throws IOException {
//Delimiter used in CSV file
final String NEW_LINE_SEPARATOR = "\n", COMMA_DELIMITER = ",";
//CSV file header
final String FILE_HEADER = "seatID,name,booked";
//fileName = System.getProperty("user.home") + "/seat.csv";
try {
fileWriter = new FileWriter(fileName);
//Write the CSV file header
fileWriter.append(FILE_HEADER.toString());
//Add a new line separator after the header
fileWriter.append(NEW_LINE_SEPARATOR);
//Write a new student object list to the CSV file
for (Seat seat : seats) {
fileWriter.append(String.valueOf(seat.getSeatID()));
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.getName());
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.isBooked());
fileWriter.append(NEW_LINE_SEPARATOR);
}
System.out.println("CSV file was created successfully !!!");
} catch (Exception e) {
System.out.println("Error in CsvFileWriter !!!");
e.printStackTrace();
} finally {
fileWriter.flush();
fileWriter.close();
}
}
reader -
public void reader() {
//Delimiter used in CSV file
final String COMMA_DELIMITER = ",";
//Student attributes index
final int SEAT_ID_IDX = 0;
final int SEAT_NAME_IDX = 1;
final int SEAT_BOOKED = 2;
//private static final int STUDENT_LNAME_IDX = 2;
BufferedReader fileReader = null;
try {
//Create a new list of student to be filled by CSV file data
List<Seat> seats = new ArrayList<>();
String line = "";
//Create the file reader
fileReader = new BufferedReader(new FileReader(fileName));
//Read the CSV file header to skip it
fileReader.readLine();
//Read the file line by line starting from the second line
while ((line = fileReader.readLine()) != null) {
//Get all tokens available in line
String[] tokens = line.split(COMMA_DELIMITER);
if (tokens.length > 0) {
//Create a new seat object and fill his data
Seat seat = new Seat(tokens[SEAT_ID_IDX],
tokens[SEAT_NAME_IDX], tokens[SEAT_BOOKED]);
seats.add(seat);
seatNo = tokens[SEAT_ID_IDX];
//System.out.println("Seat Number: " + seatNo);
bookedSeat = tokens[SEAT_BOOKED];
}
}
//Print the new student list
for (Seat seat : seats) {
System.out.println(seat.toString());
}
} catch (Exception e) {
System.out.println("Error in CsvFileReader !!!");
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
System.out.println("Error while closing fileReader !!!");
e.printStackTrace();
}
}
}//end reader
SeatingPlan - This if where I have tried to have the arguments controlling the outcome but IsBooked is colliding when multiple seats are selected.
public SeatingPlan() throws IOException {
setVisible(true);
initComponents();
//reader();
ColourSectionGold();
ColourSectionBronze();
reader();
if(R1S10.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true"))){ R1S10.setBackground(Color.red);}
//if(R1S9.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true2"))){ R1S9.setBackground(Color.red);}
}
IsSeatBooked -
public String IsSeatBooked(){
return bookedSeat;
}//end IsSeatBooked
Im using the method above as my argument to see whether a seat is booked or not, but when a new seat is click it sets the whole value of 'bookedSeat' - which leaves the system not working correctly. I understand the code is not very efficient but is there any temporary fix for this problem, if I have explained it correctly.
Also I will include my class for Seat -
public class Seat {
private String seatID;
private String booked;
private String name;
private int price;
public Seat(String seatID,String name,String booked){
this.seatID = seatID;
this.booked = "";
this.name = name;
this.price = price;
}
public String getSeatID() {
return seatID;
}
public void setSeatID(String seatID) {
this.seatID = seatID;
}
public String isBooked() {
return booked;
}
public void setBooked(String booked) {
this.booked = booked;
}
public String getStatus(){
return booked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setPrice() {
this.price = price;
}}//end class Seat
And a look at the CSV file that is created -
I wish to be able to click more than one button and save its state, Button 10 works fine at the moment, but as IsBooked only has one value at a time it clashes.
If you took the time to check this out, I appreciate it. Any constructive criticism is helpful and any ideas would be great!
Thanks,
Paddy.
Too much code to look at to see exactly what you are doing.
Instead of using your csv file, you could create a Properties file. The Propertiesfile will store the data in the form of:
key:data
So in your case the key would be the id: A1, A2... and the data would be the name of the person who booked the seat.
So the file would start out as empty. When you create the GUI you would create a loop that checks each id to see if an entry is found in the Properties field. If it is found then you display the seat as taken, otherwise it is empty.
Then whenever you want to book a seat you just use the setProperty(...) method.
The Properties class has load(...) and store(...) methods.
So the Properties class allows you to easily manage a flat file database with minimal effort.
Note, you would never have variable names like R1S10. That would requirement 100 different variables with if/else statements. Instead you would extend JButton and pass in the row and seat as parameters the button. Then in the ActionListener for the button you can access the row/seat information to built the ID used as the key for the properties file.
Edit:
Couldn't quite make the loop that checks if the ID is in the properties file.
If the property is null, the seath is empty.
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Properties properties = new Properties();
properties.setProperty("A2", "Smith");
properties.setProperty("C3", "Jones");
String[] rows = { "A", "B", "C", "D" };
int seats = 4;
for (int row = 0; row < rows.length; row++)
{
for (int seat = 1; seat <= seats; seat++)
{
String key = rows[row] + seat;
String property = properties.getProperty( key );
System.out.println(key + " : " + property);
}
}
}
}
I have a combo box that contains data from an array. I want to be able to get the the selected name in the JComboBox and print it to a text file. The problem is that the name wont write to the text file.
Array code:
public class readfiles {
String [] names = new String[15];
int i = 0;
private Scanner readNames;
//Opens the file
public void openFile() {
try {
readNames = new Scanner(new File("ChildName.txt"));
} catch (Exception e) {
System.out.println("Could not locate the data file!");
}
}
//Reads the names in the file
public void readFile() {
while(readNames.hasNext()) {
names[i] = readNames.next();
System.out.println(names[i]);
i++;
}
}
//Closes the file
public void closeFile() {
readNames.close();
}
}
ComboBox code:
//JComboBox for selecting child
JLabel selectChildName = new JLabel("Please Select Your Child:");
sPanel.add(selectChildName);
readfiles readNames = new readfiles();
readNames.openFile();
readNames.readFile();
readNames.closeFile();
JComboBox<String> selectChild = new JComboBox<String>(readNames.names);
sPanel.add(selectChild);
And finally this is what I am doing to write the selected name to a text file.
bw.write(selectChild.getSelectedIndex());
UPDATE
Used:
bw.write(selectChild.getSelectedItem().toString());
You need JComboBox#getSelectedItem() instead of JComboBox#getSelectedIndex(). As it is a String, it should be printed within the file.
Returns the current selected item.
Do not forget to also use a ItemListener with your JComboBox
I am creating my first GUI its a phonebook where users can add, show all, and delete contacts stored in a txt file. My problem here is I'm already able to write the datas to the txt file but I dont know to how delete a contact. Sorry guys newbee here.
This is how I put the data in a txt file and read it back.
private void ADD_ActionPerformed(java.awt.event.ActionEvent evt) {
inputs ++;
String[] name;
String[] number;
String[] email;
name = new String[inputs];
number = new String[inputs];
email = new String[inputs];
//arrays the inputs
for (int i = 0; i < inputs; i++) {
name [i] = name_field.getText();
number[i] = number_field.getText();
email [i] = email_field.getText();
}
name_field.setText("");
number_field.setText("");
email_field.setText("");
try (PrintWriter write = new PrintWriter(new BufferedWriter(new FileWriter("database.txt", true)))){
for (int i = 0; i < 1; i++) {
write.write("Name: "+name[i] + "\nNumber: " + number[i] + "\nEmail: " + email[i] +"\n\n");
}
} catch (IOException e) {
System.err.println("ERROR");
}
}
private void SHOW_ActionPerformed(java.awt.event.ActionEvent evt) {
try {
File f = new File("database.txt");
Scanner sc = new Scanner(f);
while (sc.hasNextLine()) {
String data = sc.nextLine();
contact_area.append("\n " + data);
}
} catch (IOException e) {
System.out.println("ERROR");
}
}
private void DELETE_ActionPerformed(java.awt.event.ActionEvent evt) {
// :( i dunno how to start
}
Unless you want to write code to search through the text file and delete that line, the easiest way to do it would be to read the entire .txt file, and add each contact to an ArrayList so that the user can add, edit, and delete contacts as they choose.
Easiest way to do that would be to make a class called "Contact" which contains a name, number, and email in each instance. Then you can manage each contact individually in the ArrayList. Here is what it would look like:
package contactbook;
public class Contact {
private String name, number, email;
public Contact(String name, String number, String email){
this.name = name;
this.number = number;
this.email = email;
}
//put setters and getters here
}
Then, when you start your program create an ArrayList like so:
ArrayList<Contact> ListOfContacts = new ArrayList<>();
//Read the text file here and create a new contact for each one read
//Display all the existing contacts on the GUI
After that, your ActionListener for the button that adds a contact would look like this:
ActionListener forAddButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
name = name_field.getText();
number = number_field.getText();
email = email_field.getText();
Contact newContact = new Contact(name, number, email);
ListOfContacts.add(newContact);
}
}
Display the contacts using a JTable and a delete button to delete the selected contact from the corresponding ArrayList element. You would do this by calling JTable.getSelectedRow() on your table model to get the correct contact in your ArrayList:
ActionListener forDeleteButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ListOfContacts.remove(myTable.getSelectedRow());
}
};
Then add a "save" button that overwrites the text file with the ArrayList ListOfContacts. Hope this helps.
The problem with my program is that once the "getMP3Tags" method is removed from the main class which is called ""musicManagerUI", and placed within it's own class, the method does not send anything over to the appropriate methods in the "musicManagerUI" class. However, if the "getMP3Tags" method is placed within the "musicManagerUI" class then everything works perfectly. I want to know why this happens and if anyone can help me to resolve this issue, as I don't want to cluster up the "musicManagerUI" class with loads of methods.
Here is the constructor for the main class "musicManagerUI":
public musicManagerUI() {
super ("Music Manager");
initComponents();
handlerClass handler = new handlerClass();
jMenuItem5.addMouseListener(handler);
}
Here is one the four methods which prints out data to the jTable:
public void printArtistName(ArrayList arrayOfArtistNames)
{
DefaultTableModel model = (DefaultTableModel) jTable2.getModel();
if (arrayOfArtistNames == null) {model.setValueAt("No Artist Names Found", 0, 0);}
else {
Object [] rowData;
rowData = new Object[3];
for (Object x : arrayOfArtistNames)
{
model.addRow(rowData);
model.setValueAt(x, counterArtist, 0);
counterArtist++;
}
}
}
Here is the code for the mousepressed handler method:
public void mousePressed(MouseEvent e) {
DefaultTableModel model = (DefaultTableModel) jTable2.getModel();
if (counterArtist == 0){}
else if (counterArtist > 0) {
model.setRowCount(0);
counterArtist = 0; counterTitle = 0; counterAlbum = 0; genre = 0;}
String FILE_DIR = "C:\\Users\\Hazzy\\Desktop\\test-data\\";
String FILE_TEXT_EXT = ".mp3";
findCertainExtension fw = new findCertainExtension();
try {
fw.getMP3Tags(FILE_DIR);
} catch (IOException ex) {
System.err.println(" Could Not read file in ");
} catch (TagException ex) {
System.err.println(" Could Not find tag");
}
}
And finally the "getMP3Tags" method:
public void getMP3Tags( String path ) throws IOException, TagException,
try{
File root = new File( path );
File[] list = root.listFiles();
ArrayList addArtistTitle = new ArrayList();
ArrayList addTrackTitle = new ArrayList();
ArrayList addAlbumTitle = new ArrayList();
ArrayList addGenre = new ArrayList();
if (list == null) return;
for ( File f : list ) {
if ( f.isDirectory()) {
getMP3Tags( f.getAbsolutePath() );
}
else if (!f.getAbsoluteFile().toString().toLowerCase().endsWith("mp3"))
{
getMP3Tags(f.getAbsolutePath());
}
else{
musicManagerUI setFields = new musicManagerUI ();
//System.out.println(f.getAbsoluteFile());
for (Object x : list) {}
MP3File mp3file = new MP3File(f.getAbsoluteFile());
ID3v2_2 name = (ID3v2_2) mp3file.getID3v2Tag();
if (name.getLeadArtist().isEmpty() == true){ name.setLeadArtist("Unknown");}
else if (name.getSongTitle().isEmpty() == true) {name.setSongTitle("Unknown");}
else if (name.getSongGenre().isEmpty() == true) {name.setSongGenre("Unknown");}
else if (name.getAlbumTitle().isEmpty() == true) {name.setAlbumTitle("Unknown");}
addArtistTitle.add(name.getLeadArtist());
addTrackTitle.add(name.getSongTitle());
addAlbumTitle.add(name.getAlbumTitle());
addGenre.add(name.getSongGenre());
}
}
musicManagerUI sendTrackInfo = new musicManagerUI();
sendTrackInfo.printArtistName(addArtistTitle);
sendTrackInfo.printTrackTitle(addTrackTitle);
sendTrackInfo.printAlbumTitle(addAlbumTitle);
sendTrackInfo.printGenre(addGenre);
}
catch(NullPointerException e){
System.err.println("Unknown Artist");
//return;
}
}
}
For this program I am using the ID3 Tagging Library/API. If you need the full code then please email me. Thanks in advance.
Some other sources which may be useful:
JTable does not show anything?
Loading Java JTable: Why does it not work?
My first thought is that in your getMP3Tags method you are calling
musicManagerUI setFields = new musicManagerUI ();
Which is creating a new instance of the musicManagerUI which has no relationship to the one that is on the screen...
What you might consider doing is passing a reference of the current instance of musicManagerUI to the method instead...
fw.getMP3Tags(FILE_DIR, this);
Assuming this is an instance of musicManagerUI which is actually been displayed...
ps- I should mention that you are actually create another instance of musicManagerUI in the getMP3Tags...
musicManagerUI sendTrackInfo = new musicManagerUI();
I've asked a similar question before, but realised the main issue at hand which I cannot solve:
Currently have an ArrayList called SundayList which is loaded as soon as the frame AddStudent is loaded (bit of GUI)
The Add Student class:
Edited
public class AddStudent extends javax.swing.JFrame {
public AddStudent() {
initComponents();
}
private void loadLists() throws IOException
{
//Creating the array of Activities to put into the ComboBoxes
File f = new File("Activities.dat");
sundayList = new ArrayList<>();
mondayList= new ArrayList<>();
tuesdayList= new ArrayList<>();
wednesdayList= new ArrayList<>();
thursdayList= new ArrayList<>();
try{
BufferedReader reader = new BufferedReader(new FileReader(f));
while(reader.ready())
{
String CDay = reader.readLine();
String CActivityName = reader.readLine();
String CSupervisor = reader.readLine();
String CLocation = reader.readLine();
String CPaid = reader.readLine();
String nothing = reader.readLine();
if(CDay.equals("Sunday"))
{
sundayList.add(CActivityName);
}
else if(CDay.equals("Monday"))
{
mondayList.add(CActivityName);
}
else if(CDay.equals("Tuesday"))
{
tuesdayList.add(CActivityName);
}
else if(CDay.equals("Wednesday"))
{
wednesdayList.add(CActivityName);
}
else if(CDay.equals("Thursday"))
{
thursdayList.add(CActivityName);
}
}
reader.close();
}
catch (IOException ex)
{
Logger.getLogger(StartUpFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
...
comboboxSunday = new javax.swing.JComboBox();
...
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AddStudent().setVisible(true);
}
});
}
For a start,I've tried to call the list SundayList into the combo box comboboxSunday to populate it, but only got the cannot find symbol error.
What do I need to do to make this possible?
Also, I plan on avoiding the mySQL involved method I've seen before, as I'm not familiar with it..
Current Coding for Combo box
The code automatically generated for the combo box by Netbeans is:
comboboxSunday = new javax.swing.JComboBox();
comboboxSunday.setModel(new javax.swing.DefaultComboBoxModel<>(sundayList.toArray(new String[sundayList.size()])));
The variable SundayList is limited to the scope of your constructor. Assuming you are creating your JComboBox in your initComponents method, you will not be able to access this variable.
You could however make SundayList a class member variable allowing you to use the variable accross methods. Also better to have a method to load data rather than having non-UI functionality in a UI constructor:
public class AddStudent {
private List<String> sundayList;
private List<String> mondayList;
...
private void loadLists() throws IOException {
sundayList = new ArrayList<>();
...
Then to add:
comboboxSunday.setModel(new DefaultComboBoxModel<>(sundayList.toArray(new String[sundayList.size()])));
Don't forget to call your new load method:
AddStudent addStudent = new AddStudent();
addStudent.loadLists();
addStudent.setVisible(true);
Aside: note that Java naming conventions indicate that variable start with a lowercase letter which would make SundayList sundayList.