I have created a text file in which to store some variables which are taken from text fields. But in order to submit new variables to this text file, I need to close my program and reopen it. The dispose(); command closes the JFrame taking me to my main menu but upon opening the menu again and submitting different values, the values from the previous time have been resubmitted. Is there a simple way to amend this?
Here is my write to .txt code:
public class writeto {
static String data = AddProperty.inputdata;
BufferedWriter out;
public writeto(){
try{
out = new BufferedWriter(new FileWriter("writeto.txt", true));
out.write(data);
out.newLine();
out.close();
}catch(IOException e){
System.out.println("you have an error" + e);
}
}
}
and where the method is called in my addproperty class
submitproperty.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
housenumber1 = houseNumber.getText();
streetname1 = streetName.getText();
town1 = town.getText();
postcode1 = postcode.getText();
beds1 = beds.getText();
price1 = price.getText();
type1 = type.getText();
inputdata = housenumber1 + " " + streetname1 + " " + town1 + " " +
postcode1 +" " + beds1 + " " + price1 + " " + type1;
writeto write = new writeto();
dispose();
}
});
}
From your menu you should always create a new JFrame with new widgets (like text fields). A new text field has no content, if you show a text field again, it will still display it's previous content.
Additional remarks:
Please use standard naming conventions - not only when you show code to others. In your case: class names shall start with a capital letter, camel-case notation is preferred (writeto -> WriteTo)
The writeto class abuses the constructor. The code in your constructor does not create an writeto object but dumps some strings to a file. Put this kind of code to a method, not to a constructor.
The BufferedWriter will not be closed if an exception occurs. Look around at stackoverflow, a lot of questions/answers show the correct io-closeing pattern
disposing the jframe is a risk - the code is executed after pressing a button (correct?), inside a method on a button that is displayed on the frame (correct?). In that case the button may be disposed while a method on the button object is still executed.. Try setVisible(false) if you just want to hide the JFrame (like "close the dialog")
You would benefit greatly from using a database as opposed to a text file. Further your question displays a fundamental lack of knowledge of not only Swing, but basic CRUD (Create, Read, Update, Delete) functionality.
To answer your question you can clear your text field with textField1.setText("");
I would read up on using a database for storing data. It will make life much easier for you.
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
In my code i have made my JtextArea public and in my code i have called the jtextare and setTextArea however when i press that button because its a thread it doesnt allow me to change the JTextArea whenever my scanner works
public void scan() throws InterruptedException {
try {
//This is the part i called it but doesnt change the jtextfield into getUid
Login login = new Login();
login.jTextField_username.setText(getUid);
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
CardTerminal terminal = terminals.get(0);
System.out.println("Waiting for a card..");
if (terminal == null) {
return;
}
terminal.waitForCardPresent(0);
Card card = terminal.connect("T=1");
System.out.println("Card: " + card);
System.out.println("Protocol: " + card.getProtocol());
CardChannel channel = card.getBasicChannel();
ResponseAPDU response = channel.transmit(new CommandAPDU(new byte[]{(byte) 0xFF, (byte) 0xCA, (byte) 0x00, (byte) 0x00, (byte) 0x00}));
System.out.println("Response: " + response.toString());
if (response.getSW1() == 0x63 && response.getSW2() == 0x00) {
System.out.println("Failed");
}
System.out.println("UID: " + bin2hex(response.getData()));
getUid = bin2hex(response.getData());
} catch (CardException ex) {
Logger.getLogger(CardId.class.getName()).log(Level.SEVERE, null, ex);
}
}
Note that we cannot compile nor run a code snippet, and so any answer given will need to include guesses, but that being said, I think that the problem is that you have a faulty assumption here:
//This is the part i called it but doesnt change the jtextfield into getUid
Login login = new Login(); // **** A ****
login.jTextField_username.setText(getUid); // **** B ****
At line A you create a new Login object, but is this the actual displayed object? I have a feeling that it's not, that you've already created and displayed the Login window, and are now creating a new one, one never displayed, and on line B are changing its state (the text held in one of its text components). If my guess is correct, then the better solution is to change the state of the actual displayed Login object, not a new and distinct one that you're creating in this method. How to do this? Impossible to state give the information that you've given so far.
If you want a more robust answer, then you will want to create and post a valid [Minimal, Complete, and Verifiable example](Minimal, Complete, and Verifiable example) in with your question -- please check out the link as it will explain all.
Other unrelated issues:
Your question mentions JTextArea, but the code suggests that we're dealing with a JTextField -- which is it?
Your question text suggests that you're mixing Scanner/console input with a Swing GUI. If this is so, I strongly urge you to not go this route, to get all input via the GUI. This will save you hours of debugging and frustration.
I'm writing a school project: a car rent system.
So far we can register a car with a model, color, etc... and an avaible character (Y/N). We are using a .txt file to save the car atributes, and another .txt file to save the clients atributes.
To rent a car we select a client, a car, then we get an unique atribute from each one (the license plate and id), save it to another .txt file, and in the car .txt file we have to change the avaible character from Y to N.
We are using an interface to do this, and we have a table with the list of clients and cars registred. First we select a client, click NEXT, then select a car and click RENT. The avaible character in the table changes from Y to N but I can't make it to save in the cars .txt file also.
I'd like some help with this
This is the code on the "register the car" window
public void persistir(){
File file = new File("carros.txt");
for(int i=0; i<qtd; i++){
try {
Veiculo carro = carros[i];
//verifica se o arquivo já existe e escreve no final do mesmo
FileWriter fileWriter = new FileWriter("carros.txt", true);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(carro.getMarca() + ";" + carro.getModelo() + ";" + carro.getCor() + ";" + carro.getCategoria() + ";" + carro.getAno() + ";" + carro.getPlaca() + ";" + carro.getDisponivel() + ";");
bufferedWriter.newLine();
bufferedWriter.close();
} catch (HeadlessException | IOException e) {
System.out.println("Erro: " + e);
}
}
}
and this is the code on the RENT button
private void finalizarActionPerformed(java.awt.event.ActionEvent evt) {
int linha = tabVeiculos2.getSelectedRow();
GPLACA = (tabVeiculos2.getValueAt(linha, 5)).toString();
tabVeiculos2.setValueAt("N", linha, 6);
Alugar(GRG,GPLACA);
JOptionPane.showMessageDialog(null, "Locação Realizada com sucesso!");
System.out.println(GPLACA);
this.dispose();
}
let me know if you need help translating something, thanks.
Edit: since you all think I just want to get my work done, I'm not. I can't make any progress since this.
Volkswagen;Gol;Preto;Popular;2016;AAA0000;Y;
Ford;Fiesta;Prata;Popular;2011;BBB1111;Y;
This is in the cars.txt file and I want to know how I change the Y to N.
It would be easiest to rewrite the whole file. That is, read and parse the file, change the data and write the file out again.
You should also consider using a standard structured file format for text files, such as xml or json. Using one of these will allow you to use libraries to read and write the data with less coding effort.
I made a code to delete the adobe directories from an user profile, I use it remotely conecting to remote computers. In this code when a file it's deleted an textArea must show the rute of the deleted file. In a System.out.println the rute it runs but it doesn't change the textArea until the recursive function ends.
I have this code. (Sorry for the rudimentary translate to English)
private void RecursiveDel(String rute) {
File tdel = new File(rute);
if (tdel.isDirectory()) {
for (File del : tdel.listFiles()) {
RecursiveDel(del.getAbsolutePath());
}
}
txtInform += "Removing: " + ruta + "\r\n";
ActRes();
tdel.delete();
System.out.println(rute);
if (tdel.exists()) {
txtInforme += "File isn't deleted: \r\n" + ruta + "\r\n";
ActRes();
Correct = false;
}
}
private void ActRes(){
Thread act = new Thread(new Runnable() {
#Override
public void run() {
txtResult.setText(txtInforme);
}
});
act.start();
}
How I can do show the deleted Files into the TextArea meanwile the recursive function works?
it runs but it doesn't change the textArea until the recursive function ends.
Correct, because your code is looping through all the directories and building a string rather than trying to update the text area for each directory.
Instead you should be using a SwingWorker and "publishing" the directory as you find it. Then every time you publish a value the text area can be updated.
Read the section from the Swing tutorial on Tasks That Have Interim Results for an example of this approach.
I have a problem about creating a textfile with the name I want.
I want to create a textfile named : 'username' Subjects.
private void saveSubjects(){
RegisterFrame r = new RegisterFrame();
String username = r.txtUser.getText();;
try{
FileWriter f = new FileWriter(username + "" + "Subjects" + ".txt", true);
String subjects[] = lstSubjects.getItems();
for(int i = 0; i<subjects.length; i++){
f.write(subjects[i] + "\r\n");
}
f.close();
JOptionPane.showMessageDialog(null, "Data saved!", "Data Saved", JOptionPane.INFORMATION_MESSAGE);
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Nothing Inputted!", "Error", JOptionPane.ERROR_MESSAGE);
}
}
I want to get the username from RegisterFrame as it is inputted there but it's not working.
I know it's a simple thing but I'm still a beginner in this. How can I solve this?
Thanks in advance
try this:
String username = r.txtUser.getText();
System.out.println("The loaded username is: " + username);
then you will see where your problem is : writing into the file OR getting the username text.
If the problem is in getting the text, consider other way of getting it or modify the question by removing the file write part and specifiing the username getting part.
Otherwise, IDK where the error is.
BTW: how is it not working? the file is not created at all? do you see any errors? the file has wrong name? please specify
Your code for writing the file seems to be fine. Based on your code I tried this which worked perfectly:
public static void main(String[] args) {
FileWriter f = null;
try {
f = new FileWriter("Subjects.txt", true);
String subjects[] = {"subject1", "subject2"};
for (String subject : subjects) {
f.write(subject + "\r\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(f);
}
}
I'd say your problem is elsewhere.
Please note that best practice dictates that Closeable objects such as FileWriter should be closed in a finally block
Assuming new RegisterFrame() starts up a GUI window, the issue is your code runs before you have a chance to type in your name. Instead you need to use event listeners to capture the contents of text fields, otherwise the code to get the name runs immediately after the window opens, long before you have a chance to type anything in.
The timeline is like this:
RegisterFrame starts a new thread to display the GUI without blocking your code
Your code immediately pulls "" from txtUser, which is of course empty
Now you type your name in
Nothing happens, because nothing in your code is paying attention to that action
Instead, it should be:
RegisterFrame starts a new thread to display the GUI without blocking your code
The method returns, or starts doing work that isn't dependent on the GUI
Now you type your name in
An event listener is triggered from the new thread, and the associated action to get the name and write to a file is executed
You have to decide what sort of listener makes sense for your use case, for instance you might want to wait until the user clicks a button (that says "Submit" or "Write File" for instance) and register an ActionListener on that button. Then you put your username polling and file writing behavior in that action* and you're golden!
*I should add that in truth you want to do as little as possible in ActionListeners, and it would be better to check if the username is not empty, then pass the actual work off to another thread, for instance with a SwingWorker, but for your purposes I suspect it will be alright to not worry about that.