OK. After spending literally a few hours trying to get things working I give up.
Basically I am creating a program in which user inputs some values, then after hitting button a new scene is created and depending on the values it was given, different things take place.
My problem - I created "Settings.class" with a few variables with getters and setters. My assumption was to store the values input in there and whenever needed I have easy access to them using getters.
For some reason it doesn't work.
Keep in mind I simplified it as much as I can because It'd look very messy and would be very long if I pasted my original code. I made sure that the core of the problem is the same.
Settings class:
public class Settings {
private boolean diamonds;
public boolean getDiamonds() {
return diamonds;
}
public void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
}
Controller class:
public class Controller implements Initializable {
private Settings settings = new Settings();
private ProblematicOne prob = new ProblematicOne();
public void handleGoAction() throws IOException {
settings.setDiamonds(true);
prob.editText("This shall be set");
/* ..creating new stage and scene here no reason to paste it here, no probs with that.. */
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
}
And crème de la crème, problematic class:
public class ProblematicOne{
private Setting settings = new Settings();
String toBeEdited = ""; //
public void editText(String text){
if(settings.getDiamonds){ // for some reason it doesn't work; The getter returns false.
toBeEdited = text;
}else if(!settings.getDiamonds){
toBeEdited = "getDiamonds is false";
}
}
}
Alright, first off, what you are trying to do can be achieved by serializing the object (i.e Settings) and storing it. Or, simpler, just write to a file with values and load from there when you want to instantiate the class.
Look at this line in your "ProblematicOne"
private Setting settings = new Settings();
You just created a new instance of Settings. This instance does not have any idea of your Settings instance in your Controller.
Another way is to make your Settings class a singleton and then just reuse it. Example:
Settings.java
public class Settings {
private static Settings instance = null;
private boolean diamonds;
public boolean getDiamonds() {
return diamonds;
}
public void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
private Settings() {}
public static Settings getInstance(){
return instance == null ? new Settings() : instance;
}
}
Then in your Controller class just get the instance using the getInstance() method;
private Settings settings = Settings.getInstance();
Similarly, when you use it again in your ProblematicOne class, use the getInstance() method
Your issue is that ProblematicClass creates a new instance of settings, so the value is not accessible. You need to pass the same instance into the other class, or make your variables in settings class static, so you can access them without instance:
public class Settings {
private static boolean diamonds;
public static boolean getDiamonds() {
return diamonds;
}
public static void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
}
And use it without instance:
Settings.setDiamonds(true);
Settings.getDiamonds();
in the following class with out setting value to settings object, you are trying to use get, which will return default value.
public class ProblematicOne{
private Setting settings = new Settings();
String toBeEdited = ""; //
public void editText(String text){
if(settings.getDiamonds){ // for some reason it doesn't work; The getter returns false.
toBeEdited = text;
}else if(!settings.getDiamonds){
toBeEdited = "getDiamonds is false";
}
}
}
if you want to use the settings object which you created in the controller then pass settings object to editText method in the ProblematicOne class.
The problem is you are instantiating Setting class twice. You set the
settings.setDiamonds(true); //in one instance
and you expect to retrive this value in second instance in class ProblematicOne.
Try to solve this by instantiating Settings only once in Controller class and pass the same to ProblematicOne. Frame your code such that you instantiate
private Setting settings = new Settings();
only once in your whole application. Consider making this class singleton. Read about singleton instantiation here
http://www.javaworld.com/article/2073352/core-java/simply-singleton.html
Related
I'm attempting to code an app that takes the users numerical specifications from the main activity in the form of a TextEdit input, convert that to an integer and then use that specific value of the integer and use that value in a separate class file which I will use the result of the class in the main activity.
Is this possible? Here's what I've attempted in the global variables of the main activity:
deadzoneValue = findViewById(R.id.TextView_deadzoneInfo);
public EditText threshold, deadzone;
public String deadzoneString = deadzone.getText().toString(); //deadzone being the name of the
public int timeLimit = Integer.parseInt(deadzoneString);
public String thresholdString = threshold.getText().toString();
public static int thresholdLimit = Integer.parseInt(thresholdString);
I'm not sure how to use these in the Deadzone class, which I'm trying to take the specific value and use there.
EDIT: Deadzone.java isn't an activity but a class with functions that are called in the MainActivity.
Using of ClassicSingleton:
public class ClassicSingleton2 {
private static String instance = null;
protected ClassicSingleton2() {
}
public static String getInstance() {
return instance;
}
public static void setInstance(String instance) {
ClassicSingleton2.instance = instance;
}
}
You could change type of instance variable to int ...
And in target code you could get this data:
xRef = ClassicSingleton2.getInstance();
This is very simple.
2:
And using of put (putExtra)
Intent oI = new Intent((FirstActivity)this,SecondActivity.class);
oI.putExtra("XRefCaller",123);
And in target code(activity) :
Bundle oBundle = getIntent().getExtras();
if(oBundle != null){
oXRefCaller = oBundle.getString("XRefCaller",-1);
//checking with -1 if the parameter does not exist or is null
}
I am just beginner in OSGi and we are still using version 4.
I have a OSGi component where one of the class has public static final (psf) variables.
What I would like to do, I want to use a fragment where it reads the values from properties file and set the values of the psf variables in the component. ? If the fragment is not found, values should be set to default.
Please find my snapshot code and let me know how can i do this ?
Component class
public final class OdsPrincipals {
/*****************************************************************************************
* Static/Inner class members
******************************************************************************************/
private static final String ODS_PRODUCT_NAME;
private static final String ODS_PRINCIPAL_NAME;
static {
//How to set the values of static final variables.
}
fragment class
public class OdsPrincipalProperties {
/*'***************************************************************************************
* Static/Inner class members
******************************************************************************************/
protected static final String ODS_PRINCIPAL_PROPERTIES_FILE = "odsprincipal.properties";
private static final Properties properties = new Properties();
static {
try {
properties.load(
OdsPrincipalProperties.class.getResourceAsStream(ODS_PRINCIPAL_PROPERTIES_FILE));
} catch (Exception e) {
ServiceLogger.error(e);
} finally {
}
}
private static final OdsPrincipalProperties odsPrincipalProperties = new OdsPrincipalProperties();
public static OdsPrincipalProperties getInstance() {
return odsPrincipalProperties;
}
/*'***************************************************************************************
* Class members
******************************************************************************************/
protected OdsPrincipalProperties() {
}
/*
* returns the value for a given key. If the key is not
* found, returns the default value.
*
*/
public String getValue(String key, String defaultValue) {
return properties.getProperty(key, defaultValue);
}
}
You want to set so called compile time constants at runtime. That is by definition not possible. The reason is that at compile time every occurrence of the variable in your code is replaced with the value of the constant. So even if you could change them at runtime the rest of your compiled code would not be updated.
So I have a class LayerCopper that holds a few textboxes and a few methods to set values in those textboxes:
public class LayerCopper extends javax.swing.JPanel {
public LayerCopper() {
initComponents();
}
private static javax.swing.JFormattedTextField CuWeightTextField;
private static javax.swing.JFormattedTextField LayerNumJFormattedTextField;
...
...
...
public void setLayerNumberText(int layerNumber) {
LayerNumJFormattedTextField.setText("" + layerNumber);
}
public void setLayerCuThickness(double CuThickness) {
CuWeightTextField.setValue(CuThickness);
}
}
I also have another class StackupCalculator with multiple instances of the LayerCopper panels in it. I have an arraylist that holds each instance of the LayerCopper panel:
static ArrayList<LayerCopper> layerSet_Copper = new ArrayList<>();
...
...
...
public void createLayerSetArray() {
layerSet_Copper.add(layerCopper1);
layerSet_Copper.add(layerCopper2);
layerSet_Copper.add(layerCopper3);
layerSet_Copper.add(layerCopper4);
layerSet_Copper.add(layerCopper5);
initializeLayerArrayValues();
}
When my initializeLayerArrayValues runs, It's supposed to populate a couple textfields with text:
private void initializeLayerArrayValues() {
for (int i = 0; i < layerSet_Copper.size(); i++) {
layerSet_Copper.get(i).setLayerNumberText(i + 1);
layerSet_Copper.get(i).setLayerCuThickness(0.750);
}
}
When I run the program though it doesn't update the fields. I'm guessing I am calling the main class LayerCopper and not the instanced version of it? How would I call the instanced version of the layer?
According to you, you haven't instantiated LayerCopper. You need to make a new instance of it, and make layerCopper1, layerCopper2, etc. Then use createLayerSetArray().
Like so:
LayerCopper lc = new LayerCopper();
// create values different layerCoppers to go in layerSet_Copper
lc.createLayerSetArray();
I don't quite understand the inner workings of your class, so I could be wrong.
Changing the textfields from static to non-static fixed it for me. /cheers
I am trying to develop a plugin for Intellij IDEA, I am working with SDK 129.451.
The issue I have is that I can't persist the user data like some list items he can input in the plugin and have the data back after the IDE restarts..
I am using PersistentStateComponent to persist the data, the getState() method seems to be called but the loadState() method doesn't.
Here is a sample class that extends PersistentStateComponent:
#State(name = "Test", storages = {#Storage(file = StoragePathMacros.APP_CONFIG+"/other.xml"
)})
public class Test implements PersistentStateComponent<Element> {
String ceva;
public Test() {
ceva = "sad";
System.out.println("constr");
}
public String getCeva() {
return ceva;
}
public void setCeva(String ceva) {
this.ceva = ceva;
}
public void loadState(Element state) {
System.out.println("cstate load");
ceva = (String) state.getContent().get(0);
}
public Element getState() {
System.out.println("cstate retu");
Element configurationsElement = new Element("testtt");
configurationsElement.addContent(ceva);
return configurationsElement;
}
}
Also I added this class in plugin.xml here:
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceImplementation="ro.catalin.prata.testflightuploader.controller.Test"/>
<!-- Add your extensions here -->
<toolWindow id="TF Uploader" secondary="true" icon="/general/add.png" anchor="right"
factoryClass="ro.catalin.prata.testflightuploader.view.TFUploader">
</toolWindow>
</extensions>
And I also have a tool window class:
public class TFUploader implements ToolWindowFactory {
private JButton buttonAction;
private ToolWindow myToolWindow;
final Test test = ServiceManager.getService(Test.class);
public TFUploader() {
// I assume it should print the saved string but it doesn't
System.out.println(test.getCeva());
buttonAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// if I click a button I am setting some new value to the string I want to save
test.setCeva(test.getCeva() + "-dddddd+");
}
});
}
Ok so, if I close the app or minimize it, the getState method gets called as I expected.. but when I open the app, the loadState method doesn't get called.. can somebody help me how I can solve this?
I already read this but it doesn't seem to help me to much. Also I want to use PersistentStateComponent as I want to save objects more complex than a simple String.
Thank you in advance!
Ok, I made it! :)
I don't know exactly what the issue was but I changed the Test class to this:
#State(
name = "Test", storages = {
#Storage(
id = "other",
file = "$APP_CONFIG$/testpersist.xml")
})
public class Test implements PersistentStateComponent<Test> {
String ceva;
public Test() {
ceva = "sad";
System.out.println("constr");
}
public String getCeva() {
return ceva;
}
public void setCeva(String ceva) {
this.ceva = ceva;
}
public void loadState(Test state) {
System.out.println("cstate load");
XmlSerializerUtil.copyBean(state, this);
}
public Test getState() {
System.out.println("cstate retu");
return this;
}
}
And in the TFUploader I changed the way I loaded the Test class to this:
final Test test = ServiceManager.getService(Test.class);
I hope it helps others..
I have already commented here but will say again that in my case loadState(MyService state) wasn't called because of lack of getter and setter for stateValue from this example:
class MyService implements PersistentStateComponent<MyService> {
public String stateValue;
public MyService getState() {
return this;
}
public void loadState(MyService state) {
XmlSerializerUtil.copyBean(state, this);
}
}
In my case I was getting a NullPointerException even before loadState was getting called. Similar to your code above I used an Element class as the state class. I had a constructor with some parameters in Element class. This was the problem as the framework could not create an instance of my state class. I tried to add a blank constructor without any parameters. This worked.
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
public class LoadSettings
{
public static void LoadMySettings (Context ctx)
{
SharedPreferences sharedPreferences = ctx.getSharedPreferences("MY_SHARED_PREF", 0);
String strSavedMem1 = sharedPreferences.getString("gSendTo", "");
String strSavedMem2 = sharedPreferences.getString("gInsertInto", "");
String cCalId = sharedPreferences.getString("gCalID", "");
setInsertIntoStr(strSavedMem2);
setSendToStr(strSavedMem1);
}
private static String cSendToStr;
private static String cInsertIntoStr;
private int cCalId;
private Uri cCalendars;
public String getSendToStr()
{
return this.cSendToStr;
}
public static void setSendToStr(String pSendToStr)
{
cSendToStr = pSendToStr;
}
public String getInsertIntoStr()
{
return this.cInsertIntoStr;
}
public static void setInsertIntoStr(String pInsertIntoStr)
{
cInsertIntoStr = pInsertIntoStr;
}
}
from the calling class i have tryed lots the current is.
LoadSettings.LoadMySettings(this);
but when i try to get some data for example.
textSavedMem1.setText(LoadSettings.getSendToStr());
i get a Null error.
LoadMySettings is not a class but a method (so it should start with a lower case, if you follow Oracle/Sun's naming conventions for the Java language).
You access it indeed by calling LoadSettings.loadMySettings(someContext), where someContext is the context to pass around. In your example, we don't know what this refers to, so maybe your error lies there.
Then when you do this: textSavedMem1.setText(LoadSettings.getSendToStr());
You call a non-static method, so that should be either using an instance of LoadSettings or, more likely considering your code, you could change getSendToStr to be:
public static String getSendToStr()
{
return cSendToStr;
}
Though that seems to be rather bad design.
Maybe if you tell us more about what you try to do, we can help more, as as such our answers will just take you one step further.
EDIT: Ok, I just figured out what you are trying to do...
You need to go back and learn basic Java concepts and read on access modifiers, and constructors first, and OO semantics in Java in general.
Change your class to this:
public class LoadSettings
{
public LoadSettings(Context ctx)
{
SharedPreferences sharedPreferences =
ctx.getSharedPreferences("MY_SHARED_PREF", 0);
String strSavedMem1 = sharedPreferences.getString("gSendTo", "");
String strSavedMem2 = sharedPreferences.getString("gInsertInto", "");
String cCalId = sharedPreferences.getString("gCalID", "");
setInsertIntoStr(strSavedMem2);
setSendToStr(strSavedMem1);
}
private String cSendToStr;
private String cInsertIntoStr;
private int cCalId;
private Uri cCalendars;
public String getSendToStr()
{
return cSendToStr;
}
public void setSendToStr(String pSendToStr)
{
cSendToStr = pSendToStr;
}
public String getInsertIntoStr()
{
return cInsertIntoStr;
}
public void setInsertIntoStr(String pInsertIntoStr)
{
cInsertIntoStr = pInsertIntoStr;
}
}
And create a new instance of LoadSettings with:
LoadSettings mySettings = new LoadSettings(someContext);
You can then correctly invoke:
textSavedMem1.setText(mySettings.getSendToStr());
Haylem has the right of it, but I just wanted to add a comment:
There are basically two design patterns in Java for what you're trying to do. One is the static class where all the methods and variables are static and you access them as e.g.
LoadSettings.loadMySettings(this);
string = LoadSettings.getSendToStr()
// etc.
The other pattern is the "singleton" class where you create exactly one instance of the class and you access the instance:
LoadSettings ls = new LoadSettings(this);
ls.loadMySettings();
string = ls.getSendToStr();
Either way is good, but what you're doing is a mish-mash of both methods and it won't work.