I would like to ask about how can I print the names of the chatters in a textfield that I created in my client file. Here is the code snippet of the server file that I have:
while (true) {
out.println("SUBMITNAME");
name = in.readLine();
if (name == null) {
return;
}
synchronized (names) {
if (!names.contains(name)) {
names.add(name);
}
break;
}
}
}
This piece of code gets the names of the chatters but I cannot display them in a textfield. Thank you very much for your help!
You can try jTextArea.append("ChatterName\n") or jTextArea.append("ChatterName<br/>"), (I think the break tag might be the issue).
But a JList IMO would be much nicer.
private DefaultListModel defaultListModel = new DefaultListModel() ;
private JList jList = new JList(defaultListModel) ;
defaultListModel.addElement(chatterName);
That appends a chatter name nicely to a JList.
Related
After searching for an answer for hours I decided to ask it here, since the solutions I found didn't work.
I have a simple GUI to register a persons first/last name and date of birth. After entering the values, the data is listed in a JList. Now I want to save the data from the JList into a Txt file. But I can't find a way to get the data from the JList.
public void save(){
try(BufferedWriter bw = new BufferedWriter(new FileWriter("jlist.txt")))
{
/* Here should be the part, where I get the data from the JList */
bw.write(person.getNachname() + " ; " + person.getVorname() + " ; " + person.getDate() + "\n");
} catch (Exception speichern) {
speichern.printStackTrace();
}
}
Later I want to take the created Txt file and load it back into the same JList.
Maybe there is even a better way to do this but I haven't found something.
Some tips would be helpful :)
There is no JList method that does this for you.
You need to get the data from the ListModel.
You get the ListModel from the JList using the getModel() method.
You need to write a loop to:
get each element from the ListModel using the getElementAt(...) method.
convert the element to a String and write the data to your file.
Some tips would be helpful
Not related to your question, but typically data like this would be displayed in a JTable. Then you have a separate column for each of the first name, last name and date. Read the section from the Swing tutorial on How to Use Tables for more information.
As camickr point out there is no method implemented for what you a trying to achieve, instead there is a combination of things that you could do for archiving your goal.
You are facing the problem of data persistence. In now-a-days for small|medium|big size industrial applications the recommended approach is to relay on databases. I guess that is out the scope for one person that is starting to code, so using files for storing info is OK but is not straightforward.
In your case, if your application is for non-commercial purposes I would suggest to use the default mechanism for serializing and deserializing objects that comes bundled with the platform. With this you could write an entire object (including its data, a.k.a. its state) to a file on a disk, and later retrieve it with few lines codes. There are details about how the object gets serialize ("translate object to bits") and deserialized ("translate bits to object") that doesn't comes into place right now, but is well to advice to study them in the future if you planning to use this method in a commercial application.
So I suggest that you load and store the information of your application on start-up and shutdown respectively, thus only one load and store per application instance, while the application is active work with the data on memory. THIS is the simplest approach you could have in any application, and for that reason I suggest to start with this ideal scenario.
So, I say a lot of things but let's goes to the code that shows an example of storing (serialize) and loading (deserialize)
import java.io.*;
import java.util.*;
class Person implements Serializable {
String name;
int birthDate;
public Person(String name, int birthDate) {
this.name = name;
this.birthDate = birthDate;
}
}
class Main {
public static void main(String[] args) {
Collection<Person> collection = createExampleCollection();
System.out.println(collection);
storeCollection(collection, "persons.data");
Collection<Person> otherCollection = loadCollection("persons.data");
System.out.println(otherCollection);
}
private static Collection<Person> createExampleCollection() {
Collection<Person> collection = new ArrayList<Person>();
collection.add(new Person("p1",0));
collection.add(new Person("p2",10));
collection.add(new Person("p2",20));
return collection;
}
// here I'm doing two separated things that could gone in separate functions, 1) I'm converting into bytes and object of an specific class, 2) saving those bytes into a file on the disk. The thing is that the platform offers us convenient objects to do this work easily
private static void storeCollection(Collection<Person> collection, String filename) {
try {
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(collection);
out.close();
fos.close();
} catch (IOException i) {
i.printStackTrace();
}
}
// again there two things going on inside, 1) loading bytes from disk 2) converting those bits into a object of a specific class.
private static Collection<Person> loadCollection(String filename) {
try {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
Collection<Person> persons = (Collection<Person>) in.readObject();
in.close();
fis.close();
return persons;
} catch (Exception i) {
i.printStackTrace();
return null;
}
}
}
You should try to use the functions of loadCollection and storeCollection on start-up and shutdown respectively.
I made this code with comments for jButton and jList in jFrame, Button saves text Items to File from jList.
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { //jButton name: "btnSave"
try { //trying to save file
BufferedWriter bw = new BufferedWriter(new FileWriter("data.txt")); //file where I store the data of jList1 (file will be stored at: C:\Users\%username%\Documents\NetBeansProjects\<ThisProjectName>\data.txt) (if You use NetBeans)
for (int i=0; i<jList1.getModel().getSize(); i++){ //opens a cycle to automatically store data of all items
bw.write(jList1.getModel().getElementAt(i)); //writing a line from jList1
bw.newLine(); //making a new line for the next item (by removing this line, You will write only one line of all items in file)
} //cycle closes
bw.close(); //file writing closes
} catch (IOException ex) { //catching the error when file is not saved
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex); //showing the error
} //Exception closes
} //Action closes
I am writing my own Netbeans plugin to edit opened files. I have managed to get some information about currently active file using
TopComponent activeTC = TopComponent.getRegistry().getActivated();
FileObject fo = activeTC.getLookup().lookup(FileObject.class);
io.getOut().println(fo.getNameExt());
io.getOut().println(fo.canWrite());
io.getOut().println(fo.asText());
But I have no idea how to modify this file. Can someone help me with this?
And second question, how to get text selection ranges? I want to run my command only on selected text.
For modifying the file you could use the NetBeans org.openide.filesystems.FileUtil.toFile() and then the regular Java stuff to read and write files and for getting the selected text of the current editor window you would have to do something like:
Node[] arr = activeTC.getActivatedNodes();
for (int j = 0; j < arr.length; j++) {
EditorCookie ec = (EditorCookie) arr[j].getCookie(EditorCookie.class);
if (ec != null) {
JEditorPane[] panes = ec.getOpenedPanes();
if (panes != null) {
// USE panes
}
}
}
For more code examples see also here
After several hours of research I found out that:
The code I posted in Question can be used to obtain basic information about active file.
To get caret position or get selection range you can do:
JTextComponent editor = EditorRegistry.lastFocusedComponent();
io.getOut().println("Caret pos: "+ editor.getCaretPosition());
io.getOut().println("Selection start: "+ editor.getSelectionStart());
io.getOut().println("Selection end: "+ editor.getSelectionEnd());
To modify content of active file (in a way that the modification can be undo by Ctrl+z) you may use this code:
final StyledDocument doc = context.openDocument();
NbDocument.runAtomicAsUser(doc, new Runnable() {
public void run() {
try {
doc.insertString(ofset, "New text.", SimpleAttributeSet.EMPTY);
} catch (Exception e) {
}
}
});
I am in the middle of creating an app that allows users to apply for job positions and upload their CVs. I`m currently stuck on trying to make a search box for the admin to be able to search for Keywords. The app will than look through all the CVs and if it finds such keywords it will show up a list of Cvs that contain the keyword. I am fairly new to Gui design and app creation so not sure how to go about doing it. I wish to have it done via java and am using the Eclipse Window builder to help me design it. Any help will be greatly appreciated, hints, advice anything. Thank You.
Well, this not right design approach as real time search of words in all files of given folder will be slow and not sustainable in long run. Ideally you should have indexed all CV's for keywords. The search should run on index and then get the associated CV for that index ( think of indexes similar to tags). There are many options for indexing - simples DB indexing or using Apache Lucene or follow these steps to create a index using Maps and refer this index for search.
Create a map Map<String, List<File>> for keeping the association of
keywords to files
iterate through all files, and for each word in
each file, add that file to the list corresponding to that word in
your index map
here is the java code which will work for you but I would still suggest to change your design approach and use indexes.
File dir = new File("Folder for CV's");
if(dir.exists())
{
Pattern p = Pattern.compile("Java");
ArrayList<String> list = new ArrayList<String>(); // list of CV's
for(File f : dir.listFiles())
{
if(!f.isFile()) continue;
try
{
FileInputStream fis = new FileInputStream(f);
byte[] data = new byte[fis.available()];
fis.read(data);
String text = new String(data);
Matcher m = p.matcher(text);
if(m.find())
{
list.add(f.getName()); // add file to found-keyword list.
}
fis.close();
}
catch(Exception e)
{
System.out.print("\n\t Error processing file : "+f.getName());
}
}
System.out.print("\n\t List : "+list); // list of files containing keyword.
} // IF directory exists then only process.
else
{
System.out.print("\n Directory doesn't exist.");
}
Here you get the files list to show now for "Java". As I said use indexes :)
Thanks for taking your time to look into my problem.
I have actually come up with a solution of my own. It is probably very amateur like but it works for me.
JButton btnSearch = new JButton("Search");
btnSearch.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
list.clear();
String s = SearchBox.getText();
int i = 0,present = 0;
int id;
try
{
Class.forName(driver).newInstance();
Connection conn = DriverManager.getConnection(url+dbName,userName,password);
Statement st = conn.createStatement();
ResultSet res = st.executeQuery("SELECT * FROM javaapp.test");
while(res.next())
{
i = 0;
present = 0;
while(i < 9)
{
String out = res.getString(search[i]);
if(out.toLowerCase().contains(s.toLowerCase()))
{
present = 1;
break;
}
i++;
}
if(tglbtnNormalshortlist.isSelected())
{
if(present == 1 && res.getInt("Shortlist") == 1)
{
id = res.getInt("Candidate");
String print = res.getString("Name");
list.addElement(print+" "+id);
}
}
else
{
if(present == 1 && res.getInt("Shortlist") == 0)
{
id = res.getInt("Candidate");
String print = res.getString("Name");
list.addElement(print+" "+id);
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
I've got a JTable that is filled by Vectors. These Vectors get their content by a loop, listing all files in a specific folder. Now I want to edit a Cell (via the GUI) that contains a filename and the real File on the HD should be renamed too. So how do I archive this?
Here's my code for the method that fills the JTable.
private void reloadFiles(){
vecVectors.clear();
if (Variables.pathToFiles != null) {
Variables.listOfFiles.clear();
Variables.listOfFiles = listFilesForFolder(Variables.pathToFiles);
for (File file : Variables.listOfFiles) {
Vector<String> temp = new Vector<String>();
temp.add(file.getName());
vecVectors.add(temp);
}
table.removeAll();
table = new JTable(vecVectors, vecHeaders);
this.remove(listScroller);
listScroller.removeAll();
listScroller = new JScrollPane(table);
listScroller.setPreferredSize(new Dimension(950, 450));
this.add(listScroller);
System.out.println("Reloaded");
}
}
Instead of using vectors to fill your table, you can use a more sophisticated table model implementation that allows you to work directly with File objects as rows in your table. I'm talking about either DataObjectTableModel or Rob Camick's RowTableModel.
So, let's say you have the table model implementation solved and each row in your table is a File object. Now, I wouldn't make any cell editable and let the table just display files info, considering:
There are many factors that can go wrong (i.e: invalid or existent file name)
It's not a TableModel responsibility to reflect the update in the HD.
It can be done using TableModelListener but the events are fired once the model has changed, so if you have troubles updating the file name in the HD then you have to revert the table model's changes. Not so easy though.
In order to re-name a file, I'd attach a MouseListener to the table and show a pop up dialog to let the user input the new file name. Finally use the File API to rename the file and update the table model reflecting these changes.
Snippet
final DataObjectTableModel<File> model = new DataObjectTableModel<File>(header) {
// Override getValueAt() and getColumnClass() here
};
final JTable table = new JTable(model);
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() >= 2 && !e.isPopupTrigger()) {
int selectedRow = table.rowAtPoint(e.getPoint());
if (selectedRow != -1) {
String newName = JOptionPane.showInputDialog (
null
, "Please input the new name"
, "Rename file"
, JOptionPane.INFORMATION_MESSAGE
);
if (newName != null) {
int modelIndex = table.convertRowIndexToModel(selectedRow);
File file = model.getDataObject(modelIndex);
// Maybe this part should be done
// using a SwingWorker to avoid blocking the EDT
String newPath = file.getParent() + File.separator + newName;
File newFile = new File(newPath);
if (file.renameTo(newFile)) {
model.deleteDataObject(modelIndex); // remove the old file
model.insertDataObject(newFile, modelIndex); // insert the new file in the same index
} else {
JOptionPane.showMessageDialog (
null
, "An error happened trying to rename file " + file.getName()
, "Error!"
, JOptionPane.WARNING_MESSAGE
);
}
}
} // if (selectedRow != -1)
} // if (e.getClickCount() >= 2 && !e.isPopupTrigger())
}
});
I have this library application that has a few different methods in its controller class. One of them is called checkOut which is used to checkout library items.
I'm trying to make this happen when the "checkout" button is now pressed and am hoping that it can get all the necessary information from the txt fields I have created.
I did the following and it is just blowing up with red errors everywhere when I press "checkout" while running. Any help is appreciated, thx!
if (source == checkoutButton)
{
/*JDialog checkout = new JDialog(checkoutContent, "Checkout", true);
JPanel panel = new JPanel();
checkout.setBounds(750, 300, 350, 190);
checkout.setResizable(false);
checkout.add(panel);
checkout.setVisible(true);*/
String borrowerID = userIDTxtField.getText();
String code = itemIDField.getText();
String date = dateField.getText();
String copyString = code.substring(1);
int copy=Integer.valueOf(copyString);
if (ctrl.checkBorrower(borrowerID))
{
boolean valid = false;
SimpleDateFormat sdf1= new SimpleDateFormat("M/dd/yyyy");
sdf1.setLenient(false);
while (!valid)
{
try
{
sdf1.parse(date);
catalogArea.setText(ctrl.checkOut(borrowerID, code, copy, date));
valid = true;
}
catch (Exception e)
{
catalogArea.setText("Date is not valid. Please try again.");
continue;
}
}
}
else
{
catalogArea.setText("Sorry Invalid ID");
}
}
while (!valid)
{
try
{
sdf1.parse(date);
catalogArea.setText(ctrl.checkOut(borrowerID, code, copy, date));
valid = true;
}
catch (Exception e)
{
catalogArea.setText("Date is not valid. Please try again.");
continue;
}
}
This code will cause an effectively infinite loop if the date is invalid. The GUI would most probably be blocked (if this is happening on the EDT - if not on the EDT, the GUI updates are incorrect) so the user would be prevented from changing the invalid date that is causing the loop.
To solve this problem, I'd look to 1st changing code not shown in the loop. Basically, the dateField (presumably a JTextField), should be a JSpinner.
See How to Use Spinners in the tutorial for that screen shot, working code, and further tips.
If the text field was instead a spinner, the entire validation shenanigans is made redundant. The spinner will provide a valid (but not necessarily correct - User Intelligence API required) date.