Using a textbox for input for a JList - java

Okay I know this has got to be something very simple I am trying to do but I am pulling my hair out trying to figure it out. I have a GUI with three text boxes and one JList I am trying to add to the list. Here is my addButton code below:
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
String emailText = custEmailTextBox.getText();
String firstText = firstNameTextBox.getText();
String lastText = lastNameTextBox.getText();
DefaultListModel<String> model = new DefaultListModel<>();
model.addElement(firstText + " : " + lastText + " : " + emailText);
custList.setModel(model);
}
I can add text to my list but if I try to add a second line of text it just overwrites the first one. How can I just add to the list with out overwriting the other?

I can add text to my jlist box but if I try to add a second line of
text it just overwrites the first one.
Because, each time your are adding a text to JList you are creating new DefaultListModel and setting that model to the JList which removes the already added texts in JList. To overcome this problem create the object of DefaultListModel once outside the addButtonActionPerformed method.Also set the model for JList once. Your code should be something like this:
DefaultListModel<String> model = new DefaultListModel<>();
private void someMethod() //call this method in your constructor or method where you have initialized your GUI
{
custList.setModel(model);
}
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
String emailText = custEmailTextBox.getText();
String firstText = firstNameTextBox.getText();
String lastText = lastNameTextBox.getText();
model.addElement(firstText + " : " + lastText + " : " + emailText);
}

By default a JList will use a DefaultListModel.
Cast the JList model via list.getModel(), and just remove your setModel method call which resets the list data.

Related

Java Swing custom JList cellRenderer not painting all elements after adding new one

So this is my first bigger project as a newbie. This project is mainly a Swing GUI application, which is basically an apartment hunter app. Actually, this is a very big program(for me at least), and the code is very messy, but i will try my best to include everything that is essential.
So in the program, one of the JPanel contains a Jlist, which contains all the available apartments, and has a custom cellRenderer class. Which looks like this(i will detail everything after the code snippet):
class PanelRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
Pair pair = sqldata.getInfo((String)value);
if(MainController.data_storage!=null){
ImageIcon final_img = MainController.data_storage.get((String)value).get(0); //(String)value is From nameList array
label.setIcon(final_img);
}
ArrayList<String> tmp = sqldata.apartmentDetails(pair.getValue()+"");
if(tmp.size()>0){
ids.add(tmp.get(tmp.size()-1));
}
label.setText("<html>Title: "+pair.getValue()+" <br/> Price: "+pair.getKey()+" <br/> Owner: "+value+"<br/> <br/>"
+ " Room type: "+tmp.get(0)+" <br/> Room num: "+tmp.get(1)+" <br/> "
+ " Balcony: "+(tmp.get(2).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Pet: "+(tmp.get(3).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Yard: "+(tmp.get(4).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Smoke: "+(tmp.get(5).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Quiet: "+(tmp.get(6).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Deposit: "+(tmp.get(7).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+"</html>");
label.setHorizontalTextPosition(JLabel.RIGHT);
value = tmp.get(tmp.size()-1);
return label;
}
}
So this line: Pair pair = sqldata.getInfo((String)value); Returns the price, and the title for an apartment.
This line: ImageIcon final_img = MainController.data_storage.get((String)value).get(0); Returns the image(s) associated with the owners name for an apartment.
The next line: ArrayList<String> tmp = sqldata.apartmentDetails(pair.getValue()+""); Returns the rest of the stuff for an apartment. eg.: City, room type, pet, etc. So one list item has an image, and some text in it.
My app has a search button, which gets all the data from the sql server when pressed, and downloads the corresponding data from a remote FTP server. And after that, the Jlist displays the result. There are filter options too, like Balcony, Pet, Price and city. These are working fine so far. The problem occurs after i upload a new apartment. If i click the search button after uploading the new apartment, everything gets returned back correctly(internally, like lists), except all the painted elems on the list. Because nothing is painted. So after the insert(upload), the data was inserted into SQL Table, Image uploaded onto FTP server. This part is fine. Furthermore, when i refresh the arrayList which gives the elements to the JList, it tells me the new apartment is in it(and the old ones too). But nothing is shown on the JList, it is completely blank. This code is doing the upload:
if(validFile()){
if(!uploadMenuValidate()){
if(!img_container.isEmpty()){
for(File f : img_container){
try {
ftp.putFileToPath(f, FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+f.getName());
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
sqldata.insert(SQLData.QUERY_ADD_APARTMENT, SQLData.APP_USERNAME,uploadmenu.getPriceField().getText(),uploadmenu.getCityField().getText(),uploadmenu.getRoomTypeSelector().getSelectedItem().toString(),
uploadmenu.getRoomNum().getText(),uploadmenu.getBalconyCheck().isSelected()+"",uploadmenu.getPetCheck().isSelected()+"",uploadmenu.getYardCheck().isSelected()+"",uploadmenu.getSmokeCheck().isSelected()+"",
uploadmenu.getFreqCheck().isSelected()+"",uploadmenu.getDepositCheck().isSelected()+"",img_container.size()>0 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(0).getName() : "",
img_container.size()>1 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(1).getName() : "",img_container.size()>2 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(2).getName() : "",
img_container.size()>3 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(3).getName() : "",uploadmenu.getDetailsBox().getText(),uploadmenu.getApTitle().getText(),mainc.getUniqueId());
showInfoPanel("misc.INFO_UPLOAD_SUCCESS");
data_storage = mainc.getApartments(sqldata.getApartments());
}
}
}
Here: data_storage = mainc.getApartments(sqldata.getApartments()); The internal ArrayList gets refreshed, which is basically contains the elements of the JList.
Some more code that could be important:
mainJListPanel = new JList(nameList);
public String[] nameList = makeList();
public String[] makeList(){
int n = sqldata.getApartments().size();
HashMap<String,List<String>> kt = sqldata.getApartments();
String[] tmp =new String[n];
ids = new ArrayList<>();
int i = 0;
for (String x : kt.keySet()){
tmp[i++] = x; //Getting the owner names
}
return tmp;
}
public static String[] searchList(){
int n = MainController.data_storage.size();
String[] tmp = new String[n];
int i = 0;
for (String x : MainController.data_storage.keySet()){
tmp[i++] = x;
}
return tmp;
}
And the search button does this:
data_storage = getApartments(sqldata.getSearchedApartments(mainmenu.getMenuMinPrice().getText()+"",mainmenu.getMenuMaxPrice().getText(),mainmenu.getMenuCity().getText(),
String.valueOf((int)mainmenu.getMenuRoomNum().getValue()),mainmenu.getMenuRoomType().getSelectedItem()+"",mainmenu.getMenuBalcony().isSelected()+"",mainmenu.getMenuYard().isSelected()+"",mainmenu.getMenuPet().isSelected()+"",
mainmenu.getMenuSmoke().isSelected()+"",mainmenu.getMenuFreq().isSelected()+"",mainmenu.getMenuDeposit().isSelected()+"", mainmenu.getMenuMiscText().getText()));
//Getting everything from the filter, and //converting it into an SQL query --> This is working, the sql command is OK.
mainmenu.setNameList(mainmenu.searchList());
mainmenu.getMenuMainPanel().revalidate();
mainmenu.getMenuMainPanel().repaint();
//mainmenu is the instance of the JPanel, which contains the Jlist
The strange thing is, if i check a filter option, like Balcony, the JList paints the result. Even the new apartment is in the result, which was uploaded. But when i remove all the filters, (So basically i want every apartment back), the list wont paint anything. So the error comes only if i'm a in a state of "after uploading", and i want every apartment to be painted on the Jlist. If i restart the program, the new apartment will be painted on the list, and everything works fine until i upload a new apartment again.

Swing - Updating element in JList after modifing it in another frame

I have the following code
DefaultListModel<String> modelPacientes = new DefaultListModel<>();
JList <String> listPacientes = new JList<>( modelPacientes );
listPacientes.setToolTipText("Lista de los pacientes del doctor");
GridBagConstraints gbc_listPacientes = new GridBagConstraints();
gbc_listPacientes.fill = GridBagConstraints.BOTH;
gbc_listPacientes.gridx = 0;
gbc_listPacientes.gridy = 0;
pPacientes.add(listPacientes, gbc_listPacientes);
modelPacientes.addElement(raul.getName() + " " + raul.getSurname());
modelPacientes.addElement(paula.getName() + " " + paula.getSurname());
modelPacientes.addElement(sara.getName() + " " + sara.getSurname());
I am modifying the values of the objects (raul, paula and sara) in another frame, how could I update it in the JList or anywhere else (JLabel) after closing the other frame?
I am modifying the values of the objects
Then the ListModel should contain the Objects not a String. So assuming your Objects are of type User you would do something like:
DefaultListModel<User> modelPacientes = new DefaultListModel<User>();
JList<User> listPacientes = new JList<User>( modelPacientes );
modelPacientes.addElement(raul);
modelPacientes.addElement(paula);
modelPacientes.addElement(sara);
Then in the User class you can override the toString() method to return the value you want to display in the JList:
#Override
public String toString()
{
return getName() + " " + getSurname();
}
I am modifying the values of the objects (raul, paula and sara) in another frame
Then you get the User object you want to modify from the ListModel and pass this object to your JDialog (note you should be using a JDialog, not a JFrame for a popup child window).
Then you update the data in the User object and when the dialog closes you invoke repaint() on the JList.
You can either provide your own subclass of ListModel (or DefaultListModel) that returns patient.getName() + " " + patient.getSurname()) in method getElementAt
or you can move the creation of the modelPacientes to a new method:
ListModel createModel() {
DefaultListModel<String> modelPacientes = new DefaultListModel<>();
modelPacientes.addElement(raul.getName() + " " + raul.getSurname());
modelPacientes.addElement(paula.getName() + " " + paula.getSurname());
modelPacientes.addElement(sara.getName() + " " + sara.getSurname());
return modelPacientes;
}
then build an empty JList instead and run listPacientes.setModel(createModel()) whenever the pacientes have changed.
This approach is fine if you have a couple dozens patients.
If you have hundreds or thousands of patients, it is probably worthwhile to you have your own model classes that map from your patient data into whatever the Swing component needs.
Add the objects (raul, paula and sara) to the list modal. Then create a ListCellRenderer that will return a string that is the "display name" for example:
raul.getName() + " " + raul.getSurname()
That way when the name of raul, paula and/or sara changes it will automatically change in the list if it is the same instance of the object.

Create Swing Components in a loop and access them

I need to read a configuration file and put the data (it consists of key-value-pairs) into some textFields I have to create dynamically in a JFrame.
After that I want to modify the textFields and save the changes to the file again.
What I have so far:
FileConfiguration fileConfig = new PropertiesConfiguration(new File("xesfile.properties"));
Iterator<String> keys = fileConfig.getKeys();
while (keys.hasNext()) {
String singleKey = keys.next();
//for the case that a key has multiple values
if (fileConfig.getProperty(singleKey).getClass().equals(ArrayList.class)) {
ArrayList<String> blaArray = (ArrayList<String>) fileConfig.getProperty(singleKey);
for (int i = 0; i < blaArray.size(); i++) {
this.keyLabel = new JLabel(this.nameKeyLabel + this.count);
this.entityLabel = new JLabel(this.nameEntityLabel + this.count);
this.keyTextField = new JTextField();
this.keyTextField.setName(this.nameKeyTextField + this.count);
this.keyTextField.setText(singleKey);
this.entityTextField = new JTextField();
this.entityTextField.setName(this.nameEntityTextField + this.count);
this.entityTextField.setText(blaArray.get(i));
this.count++;
this.configFrame.add(this.keyLabel);
this.configFrame.add(this.keyTextField);
this.configFrame.add(this.entityLabel);
this.configFrame.add(this.entityTextField);
this.configFrame.revalidate();
this.configFrame.repaint();
this.configFrame.pack();
}
//for the case a key has a single value
} else {
this.keyLabel = new JLabel(this.nameKeyLabel + this.count);
this.entityLabel = new JLabel(this.nameEntityLabel + this.count);
this.keyTextField = new JTextField();
this.keyTextField.setName(this.nameKeyTextField + this.count);
this.keyTextField.setText(singleKey);
this.entityTextField = new JTextField();
this.entityTextField.setName(this.nameEntityTextField + this.count);
this.entityTextField.setText((String) fileConfig.getProperty(singleKey));
this.count++;
this.configFrame.add(this.keyLabel);
this.configFrame.add(this.keyTextField);
this.configFrame.add(this.entityLabel);
this.configFrame.add(this.entityTextField);
this.configFrame.revalidate();
this.configFrame.repaint();
this.configFrame.pack();
}
}
As you see the TextFields are created again and again in every pass of the while-loop. But I need to access the textFields I created in the first pass of the loop for the example.
Thought if I would access the TextFields with getName() they would be returned, but that's not the case.
Can anyone help me out?
Store your TextField in a Map with key as name and value as TextField object itself. You could later access it using:
TextField textField = map.get("myField");
This is so simple
// In loop
1) Create the component.
2) Add it to an Generic ArrayList
3) You can also attach an actionListener to the component in loop if you want.
// Out of loop
4) Iterate the ArrayList and access the desire component.

how to populate data from textarea to jlist

I'm having a problem with the jlist..the data is showing in my jlist whenever i put a data on my textarea but instead of populating the data it will remove the previous one and will only show the current input.. here is my code by the way
private void postButtonActionPerformed(java.awt.event.ActionEvent evt) {
String theAccountID = showAccountID.getText();
String theFirstName = showFName.getText();
String theLastName = showSName.getText();
String name = theFirstName + " " + theLastName;
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date date = new Date();
String dateAndTimeCreated = dateFormat.format(date);
String show = thePost.getText();
Post obj = new Post(show);
String post = obj.getContent();
DefaultListModel model = new DefaultListModel();
String postOutput = dateAndTimeCreated + " " + name + ": " + post;
try
{
if(obj.getContent().equals(""))
{
JOptionPane.showMessageDialog(null, "This status update appears to be blank. Please write something to update your status.");
}
else
{
model.addElement(postOutput);
showPostStatus.setModel(model);
String sql = "insert into Post(account_id,post,datePostCreated) values (?,?,?)";
pst = conn.prepareStatement(sql);
pst.setString(1,theAccountID);
pst.setString(2,post);
pst.setString(3,dateAndTimeCreated);
pst.execute();
pst.close();
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null,e);
}
thePost.setText(null);
}
You are re-creating the ListModel each time postButtonActionPerformed is called, this (effectively) discards everything else that the JList was displaying in favor of the contents of the new model
You could consider create a DefaultListModel as an instance field, set it as the JLists model and simply update this model as required
You could also do something like...
DefaultListModel model = (DefaultListModel)showPostStatus.getModel();
// update the model...
You won't need to apply the model, as any changes you make will be reflected within the JList itself automatically...

New line using JLabel and java variable from ArrayList

I create a button that will onclick show in a separate window (like you see below) the list of all users from my database.
But, they are displayed all in one line! Even though I put /n - it just wont work. I mean, it work in console when I use Sys.out but when I go to the Window and put it there it is all in one line :(
What should I change in order to display all of the users one below another.
public class ViewAll {
private String listax = "";
ViewAll() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException{
ArrayList<String[]> allUsers = DbBroker.getArray("select * from user");
for(String[] usr : allUsers)
listax += usr[0] + ")" + usr[1] + ", " + usr[2] + ", " + usr[3] + "\n";
}
public void display() {
JFrame lis = new JFrame("List of all users");
lis.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
lis.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel pane = new JPanel(new GridLayout(0,1));
lis.add(pane);
pane.add(new JLabel("This is the complete list of all users in my db: "));
pane.add(new JLabel(listax));
lis.pack();
lis.setSize(500,400);
lis.setVisible(true);
}}
I suggest that you don't use a JLabel but instead use a JList. It was built to do just this sort of a thing. The key here being: use the right tool for the job. It also appears that you're trying to use a JFrame in a dialog capacity, and if so, don't -- use a JDialog instead, or even a JOptionPane:
public void display(List<String> userList) {
DefaultListModel<String> listModel = new DefaultListModel<String>();
for (String user : userList) {
listModel.addElement(user);
}
JList<String> userLabel = new JList<String>(listModel);
JScrollPane scrollPane = new JScrollPane(userLabel);
String title = "This is the complete list of all users in my db:";
// mainJFrame is the main JFrame for the GUI
JOptionPane.showMessageOption(mainJFrame, scrollPane, title,
JOptionPane.PLAIN_MESSAGE);
}

Categories