I am creating a client-server chat application and I intend required to store the username for a better user experience.As soon as I fire the main method, the load() method is called.This method sets the user name automatically by reading from the configurations file.The configuration file is not null (I have the user name stored). But the textField is not updating.Any ideas?Here is my load method:
public static void load()
{
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("config.properties");
prop.load(input);
textField.setText(prop.getProperty("user")); //not updating!!!!
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Thanks for your help, guys.I figured out the problem.Actually, I had declared textfield as:
static JTextField textField=new JTextField();
outside main() and then again as:
textField=new JTextField();
inside the constructor.I removed the one inside the constructor and it solved the problem.
Once again thank you all for your help.
To add on to what Andreas Fester said above. You should first do a check on the file, if it exists or not, this will allow you to verify you are pointing to the right directory in the case the root of the project. Also add a clause saying something like if(prop.getProperty("user")==null){//handle null} then also try using textField.append("text"); just to see a different method and then verify by doing System.out.println("TextField: "+textField.getText()) to see if it is setting the text
If anything look at this demo given by oracle to use textfield. Also its a good practice to know when to separate member variable (belongs to instance) or class variables(static), I would avoid static like in the demo provided.
hope this helps.
Related
In fact I am making a Minecraft plugin and I was wondering how some plugins (without using DB) manage to keep information even when the server is off.
For example if we make a grade plugin and we create a different list or we stack the players who constitute each. When the server will shut down and restart afterwards, the lists will become empty again (as I initialized them).
So I wanted to know if anyone had any idea how to keep this information.
If a plugin want to save informations only for itself, and it don't need to make it accessible from another way (a PHP website for example), you can use YAML format.
Create the config file :
File usersFile = new File(plugin.getDataFolder(), "user-data.yml");
if(!usersFile.exists()) { // don't exist
usersFile.createNewFile();
// OR you can copy file, but the plugin should contains a default file
/*try (InputStream in = plugin.getResource("user-data.yml");
OutputStream out = new FileOutputStream(usersFile)) {
ByteStreams.copy(in, out);
} catch (Exception e) {
e.printStackTrace();
}*/
}
Load the file as Yaml content :
YamlConfiguration config = YamlConfiguration.loadConfiguration(usersFile);
Edit content :
config.set(playerUUID, myVar);
Save content :
config.save(usersFile);
Also, I suggest you to make I/O async (read & write) with scheduler.
Bonus:
If you want to make ONE config file per user, and with default config, do like that :
File oneUsersFile = new File(plugin.getDataFolder(), playerUUID + ".yml");
if(!oneUsersFile.exists()) { // don't exist
try (InputStream in = plugin.getResource("my-def-file.yml");
OutputStream out = new FileOutputStream(oneUsersFile)) {
ByteStreams.copy(in, out); // copy default to current
} catch (Exception e) {
e.printStackTrace();
}
}
YamlConfiguration userConfig = YamlConfiguration.loadConfiguration(oneUsersFile);
PS: the variable plugin is the instance of your plugin, i.e. the class which extends "JavaPlugin".
You can use PersistentDataContainers:
To read data from a player, use
PersistentDataContainer p = player.getPersistentDataContainer();
int blocksBroken = p.get(new NamespacedKey(plugin, "blocks_broken"), PersistentDataType.INTEGER); // You can also use DOUBLE, STRING, etc.
The Namespaced key refers to the name or pointer to the data being stored. The PersistentDataType refers to the type of data that is being stored, which can be any Java primitive type or String. To write data to a player, use
p.set(new NamespacedKey(plugin, "blocks_broken"), PersistentDataType.INTEGER, blocksBroken + 1);
For bilingual support in an application I am working on, we are using Spring messaging which uses two files, ApplicationResources.properties and ApplicationResources_fr.properties. This works well.
Now I am trying to expand on this by making it a little more dynamic. The application will read key value pairs from the database and insert them, which gives me the following error:
java.io.FileNotFoundException: \ApplicationResources.properties (Access is denied)
I am able to check on the key value pairs so I know the path I am using is correct. I have also checked the files in Eclipse properties by right clicking, and by visiting the actual file on my system, and they are not read-only. I do not believe they are encrypted because I am able to open and view with notepad++.
Here is my testing code which shows I can view them
Properties test_prop = null;
InputStream is = null;
try {
test_prop = new Properties();
is = this.getClass().getResourceAsStream(en_path);
test_prop.load(is);
Set<Object> keys = test_prop.keySet();
boolean key_found = false;
for(Object k:keys) {
String key = (String)k;
if(key.equals("f12345"))
{
key_found=true;
break;
}
}
System.out.println("Language Properties Test in DAO:" + (key_found? "Key Found" : "Key not found"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Here is where I try to write to the file, and get the error:
ResultSet rs = null;
try (
Connection connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(test_prod_cur);
)
{
callableStatement.registerOutParameter(1, OracleTypes.CURSOR);
callableStatement.executeUpdate();
rs = (ResultSet) callableStatement.getObject(1);
while (rs.next())
{
String thead = rs.getString(1);
//System.out.println(thead + " " + rs.getString(2) + " " + rs.getString(3));
en_prop.setProperty(keyheader+thead, rs.getString(2));
fr_prop.setProperty(keyheader+thead, rs.getString(3));
}
}
catch (SQLException e)
{
System.out.println("SQLException - bilingual values - CLUDAOImpl");
System.out.println(e.getMessage());
}
//add to properties files
//*
try (OutputStream en_os = new FileOutputStream(en_path);)
{
en_prop.store(en_os, null);
} catch (IOException e) {
e.printStackTrace();
}
try(OutputStream fr_os = new FileOutputStream(en_path);)
{
fr_prop.store(fr_os, null);
} catch (IOException e) {
e.printStackTrace();
}
So the database query is successful, that was tested with the commented out system.out.println. It is the following lines that end up throwing the error:
en_prop.store(en_os, null);
fr_prop.store(fr_os, null);
Update: I did a search on the java.util.Properties which lead me to the javadocs on it and wow does that simplify many things. I can now grab a property value or check if the key exists in 6 lines of code (not counting try catch).
Properties prop = null;
InputStream is = null;
this.prop = new Properties();
is = this.getClass().getResourceAsStream(path);
prop.load(is);
this.prop.getProperty("key name"); //returns value of key, or null
this.prop.containsKey("key name"); //returns true if key exists
Update2: There is an issue using java.util.Properties and that is you lose all formatting of the original file, so white-space, comments, and ordering are all lost. In another answer someone suggested using Apache's Commons Configuration API. I plan on trying it out.
So I ended up creating a class to handle interactions with the ApplicationResources(_fr).properties files instead of doing it in the DAO. This was because I plan on using it in more places. I also started using methods from the java.util.Properties Javadocs which proved very helpful and simplified many areas.
Below is my new file write/properties store code.
try (
OutputStream en_os = new FileOutputStream(getClass().getResource(en_path).getFile(),false);
OutputStream fr_os = new FileOutputStream(getClass().getResource(fr_path).getFile(), false);
)
{
en_prop.store(en_os, null);
fr_prop.store(fr_os, null);
} catch (IOException e) {
e.printStackTrace();
}
Lets compare the new and original OutputStreams:
OutputStream en_os = new FileOutputStream(getClass().getResource(en_path).getFile(),false); //new
OutputStream en_os = new FileOutputStream(en_path); //original, Access is Denied
This answer is incomplete for the following reasons.
I am unable to explain why the original method failed and resulted in a "Access is denied error".
More concerning reason to me, this doesnt actually alter the file I am expecting or wanting. I expected to alter the file that appears in my project navigator, but when viewed changes are not observed. If I use an absolute path (C:\...) and overwrite the file then I can alter it as expected, but this path would have to be changed as servers are changed and its bad programming and dangerous. This working method is altering some kind of temp or running file (as confirmed via the path as the file that shows the new values is in the tmp0 folder). After some testing, this temporary file is overwritten on startup only when the original file has been changed, otherwise the new values persist across application starting.
I am also unsure as to the scope of this file. I am unable to tell if all users interacting with the website would cause changes to the same file. If all users are interacting with the file, then potential leakage across sessions could occur. It is also possible that each session has isolated values and could lead to missing information. I suspect that all users are interacting with the same resource but have not performed the testing required to be absolutely positive about this. UPDATE: I have confirmed that all users interact with the same temporary file.
I'm messing around with Java NIO and for some reason I can't get Files.isHidden() to return the correct boolean value. The program just checks to see if the directory is hidden then if it is hidden will make it visible and if it is not hidden it will make it hidden. This is what I have:
Path start = FileSystems.getDefault().getPath("E:/Documents/someDirectory");
try {
if (Files.isHidden(start)){
System.out.println("Dir is hidden.");
Files.setAttribute(start, "dos:hidden", false);
} else {
System.out.println("Dir is not hidden. Hiding.");
Files.setAttribute(start, "dos:hidden", true);
}
} catch (IOException e) {
e.printStackTrace();
}
It keeps returning false and hiding the directory despite the directory being hidden. The following code works fine using the old File class w/ the Path class.
Path start = FileSystems.getDefault().getPath("E:/Documents/someDirectory");
File file = new File("E:/Documents/someDirectory");
try {
if (file.isHidden()){
System.out.println("Dir is hidden.");
Files.setAttribute(start, "dos:hidden", false);
} else {
System.out.println("Dir is not hidden. Hiding.");
Files.setAttribute(start, "dos:hidden", true);
}
} catch (IOException e) {
e.printStackTrace();
}
As already pointed out in the comments, the documentation of Files.isHidden states:
The exact definition of hidden is platform or provider dependent. […] On Windows a file is considered hidden if it isn't a directory and the DOS hidden attribute is set.
While the last cited sentence already explains while it doesn’t return the expected value for a directory on Windows, I want to emphasize the first sentence. You are using a method burdened with a platform/provider specific semantics, while all you want to do, is to toggle a particular, platform specific flag.
In that case, you should just do exactly that, which also elides the conditionals of your code:
Path start=Paths.get("E:/Documents/someDirectory");
boolean isHidden=(Boolean)Files.getAttribute(start, "dos:hidden");
System.out.println("Dir is "+(isHidden? "hidden. Showing.": "not hidden. Hiding"));
Files.setAttribute(start, "dos:hidden", !isHidden);
Note also the convenience method Paths.get(…) for FileSystems.getDefault().getPath(…).
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.
We are using the new Java printing API which uses PrinterJob.printDialog(attributes) to display the dialog to the user.
Wanting to save the user's settings for the next time, I wanted to do this:
PrintRequestAttributeSet attributes = loadAttributesFromPreferences();
if (printJob.printDialog(attributes)) {
// print, and then...
saveAttributesToPreferences(attributes);
}
However, what I found by doing this is that sometimes (I haven't figured out how, yet) the attributes get some bad data inside, and then when you print, you get a white page of nothing. Then the code saves the poisoned settings into the preferences, and all subsequent print runs get poisoned settings too. Additionally, the entire point of the exercise, making the settings for the new run the same as the user chose for the previous run, is defeated, because the new dialog does not appear to use the old settings.
So I would like to know if there is a proper way to do this. Surely Sun didn't intend that users have to select the printer, page size, orientation and margin settings every time the application starts up.
Edit to show the implementation of the storage methods:
private PrintRequestAttributeSet loadAttributesFromPreferences()
{
PrintRequestAttributeSet attributes = null;
byte[] marshaledAttributes = preferences.getByteArray(PRINT_REQUEST_ATTRIBUTES_KEY, null);
if (marshaledAttributes != null)
{
try
{
#SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"})
ObjectInput objectInput = new ObjectInputStream(new ByteArrayInputStream(marshaledAttributes));
attributes = (PrintRequestAttributeSet) objectInput.readObject();
}
catch (IOException e)
{
// Can occur due to invalid object data e.g. InvalidClassException, StreamCorruptedException
Logger.getLogger(getClass()).warn("Error trying to read print attributes from preferences", e);
}
catch (ClassNotFoundException e)
{
Logger.getLogger(getClass()).warn("Class not found trying to read print attributes from preferences", e);
}
}
if (attributes == null)
{
attributes = new HashPrintRequestAttributeSet();
}
return attributes;
}
private void saveAttributesToPreferences(PrintRequestAttributeSet attributes)
{
ByteArrayOutputStream storage = new ByteArrayOutputStream();
try
{
ObjectOutput objectOutput = new ObjectOutputStream(storage);
try
{
objectOutput.writeObject(attributes);
}
finally
{
objectOutput.close(); // side-effect of flushing the underlying stream
}
}
catch (IOException e)
{
throw new IllegalStateException("I/O error writing to a stream going to a byte array", e);
}
preferences.putByteArray(PRINT_REQUEST_ATTRIBUTES_KEY, storage.toByteArray());
}
Edit: Okay, it seems like the reason it isn't remembering the printer is that it isn't in the PrintRequestAttributeSet at all. Indeed, the margins and page sizes are remembered, at least until the settings get poisoned at random. But the printer chosen by the user is not here:
[0] = {java.util.HashMap$Entry#9494} class javax.print.attribute.standard.Media -> na-letter
[1] = {java.util.HashMap$Entry#9501} class javax.print.attribute.standard.Copies -> 1
[2] = {java.util.HashMap$Entry#9510} class javax.print.attribute.standard.MediaPrintableArea -> (10.0,10.0)->(195.9,259.4)mm
[3] = {java.util.HashMap$Entry#9519} class javax.print.attribute.standard.OrientationRequested -> portrait
It appears that what you're looking for is the PrintServiceAttributeSet, rather than the PrintRequestAttributeSet.
Take a look at the PrintServiceAttribute interface, and see if the elements you need have been implemented as classes. If not, you can implement your own PrintServiceAttribute class(es).