I am trying to access a form which is not static from another class which is also not static. I'd like to use a member in the class....
Public Class MainForm
public void setConsoleText(String Text){
jTextArea1.append(Text);
}
I need to know a way to reference this setter from my class "Log" which is basically where data goes to be parsed and logged. I want it to be like this:
private void consoleOut(String data) {
System.out.println(data);
MainForm.setConsoleText("data");
}
I cannot access this method.. I can only access MyForm.Class. Is there a way to reference the one that's been instantiated, or all of them in this virtual machine? It really doesn't matter as there will only be one of these running in this instance of the Java VM.
I just can't seem to figure this one out.
You need to give Log a non-static MainForm variable and pass reference to the currently visualized MainForm object into the Log class and into this variable. This can be done via a Log constructor parameter or via a setter method. Then you can call methods on this instance (but checking that it's not null first). Something like:
public class Log {
private MainForm mainForm; // our MainForm variable
public Log(MainForm mainForm) {
// setting the MainForm variable to the correct reference in its constructor
this.mainForm = mainForm;
}
private void consoleOut(String data) {
System.out.println(data);
if (mainForm != null) {
// now we can use the reference passed in.
mainForm.setConsoleText("data");
}
}
}
Edit 1
For instance if you create your MainForm object and display it from a main method somewhere, create Log along with it and pass the visualized MainForm into the Log constructor, something like so:
public static void main(String[] args) {
MainForm myMainForm = new MainForm();
// ... whatever code is necessary to set up the
// ... MainForm object so it can be visualized
myMainForm.setVisible(true); // and show it
Log myLogObject = new Log(myMainForm);
//...
}
Note that if this doesn't help you, you'll need to post more of your code.
Related
I want to use inst in another class SubscribeTables() I need it with all of its data. I tried to make a getter in Main() but it didnt work. Maybe i can pass it to another class somehow? Can someone help me with it?
Lets say i need to call inst.isConnected() in SubscribeTables()
public class Main {
public static void main(String[] args) throws IOException {
// Setup NT4 Client
NetworkTableInstance inst = NetworkTableInstance.getDefault();
inst.startClient4("FRC Stat Track");
selectNetworkTablesIP(inst, 5883);
// Connects after ~100ms
new SubscribeTables();
}
So to consolidate, in terms of code, your SubscribeTables class should look like this:
public class SubscribeTables {
private NetworkTableInstance instance;
// Make a constructor to take NetworkTableInstance
public SubscribeTables(NetworkTableInstance instance) {
this.instance = instance;
}
public void function() {
// Use the NetworkTableInstance for every function in this Class
boolean isConnected = instance.isConnected();
}
}
And the way to create a SubscribeTables object:
SubscribeTables tables = new SubscribeTables(inst);
The scope of NetworkTableInstance inst is limited to the lifecycle of main method as your new class is not aware. You have 2 options if you still want to do it in this way - but not recommened.
Pass the instance of NetworkTableInstance as a constructor paramater to SubscribeTables
Pass the instance of NetworkTableInstance to the respective methods as a method parameter you need to call on SubscribeTables
You can supply link of object A(type NetworkTableInstance) to object B(type SubscribeTables) either by argument in constructor or by argument in setter method. In both cases SubscribeTables class should have field of type NetworkTableInstance to put NetworkTableInstance object from constructor or setter arguments into the field.
I want to access the checkWord variable in the main code block. I don't know how to access it globally. How can I access a local variable in main in Java?
This is example code blocks.
textField.setOnAction(event -> {
try{
ArrayList<String> wordList = wordListReader();
boolean checkWord = false;
for(String word:wordList){
if(word.equals(textField.getText())){
checkWord = true;
}
}
System.out.println(checkWord);
}catch (FileNotFoundException ex){
ex.printStackTrace();
}
});
// Error
System.out.println(checkWord);
Design-wise, global variables (static fields in Java) are usually not a great idea because it causes a tight coupling between classes, making it harder to make changes to the system later on.
That said, to do what you describe you would do this:
public class YourClass {
// class field
public static boolean checkWord;
// instance (object) field
private TextField textField = new TextField("Your text field");
public void yourMethod() {
textField.setOnAction(event -> {
// ...
checkWord = true;
// ...
});
System.out.println(checkWord);
}
public static void iDoNotKnowAboutInstances() {
// OK
System.out.println(checkWord);
// Compile error - cannot refer to instance field in static context
System.out.println(textField);
}
}
Meanwhile, in another class:
public class YourOtherClass {
public void yourOtherMethod() {
System.out.println(YourClass.checkWord);
}
}
A static field exists at class level. It is initialized when the class is loaded by the class loader for the first time, in this case it will be initialized as false (the default for booleans). Then, when yourMethod is executed and an event is handled, the field checkWord is set to true. It can be referred to directly from within the same class. From another class it can be referred to by prefixing the class name, as shown in YourOtherClass.
EDIT: Not that you can refer to static fields from anywhere (as long as their visibility qualifier allows it) but you only refer to instance field via an actual instance. So for example from the static method iDoNotKnowAboutInstances you cannot refer to instance field textField. You often run into this when you create a simple java application with the entry method public static void main(String[] args). If you then add instance fields to the class you will first need to create an instance of the class using YourClass instance = new YourClass() to be able to read and write those fields.
I have some code that I need to reuse in several Java apps. That code implements a GUI which in turn needs to access some static variables and methods from the calling class. Those variables and methods are always called the same in all of the apps. Is there a generic way to obtain a handle to the calling class in Java so the code for "someGUI" class can remain untouched and in fact come from the same source file for all the different apps?
Minimal working example:
import javax.swing.*;
class test {
static int variable = 123;
public static void main(String[] args) {
someGUI sg = new someGUI();
sg.setVisible(true);
}
}
class someGUI extends JFrame {
public someGUI() {
System.out.println(String.format("test.variable = %d", test.variable));
}
}
How can I "generify" the reference to "test" in test.variable to always just refer to the calling class? It's not the "super" class, at least using super.variable doesn't work.
Firstly I would advise against this approach since there are only brittle ways to implement it. You should parameterize SomeGUI with a parameter containing the values you need instead.
However, it is possible to do what you ask by examining the thread's stack trace and using reflection to access the static fields by name. For example like this:
class Test {
static int variable = 123;
public static void main(String[] args) throws Exception {
SomeGUI sg = new SomeGUI();
}
static class SomeGUI extends JFrame {
public SomeGUI() throws Exception {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
// stackTrace[0] is getStackTrace(), stackTrace[1] is SomeGUI(),
// stackTrace[2] is the point where our object is constructed.
StackTraceElement callingStackTraceElement = stackTrace[2];
String className = callingStackTraceElement.getClassName();
Class<?> c = Class.forName(className);
Field declaredField = c.getDeclaredField("variable");
Object value = declaredField.get(null);
System.out.println(String.format("test.variable = %d", value));
}
}
}
This will print test.variable = 123.
Obviously this is sensitive to renaming of the variables. It is also sensitive to dynamic proxies.
Also, it should be noted that you need to do this in the constructor. If you try to do this kind of lookup in other methods you can not find out how the instance was created.
There is no inheritance between somGUI and test,
Actual inheritance is there between someGUI and JFrame.
If you use super(), JVM tries to find 'variable' in JFrame, that is not what you wanted.
Use static methods setters & getters to access the 'variable' instead of direct accessing them.
I have the following two classes:
public class Class1
{
public Class1 randomvariable; // Variable declared
public static void main(String[] args)
{
randomvariable = new Class1(); // Variable initialized
}
}
public class Class2
{
public static void ranMethod()
{
randomvariable.getSomething(); // I can't access the member "randomvariable" here even though it's public and it's in the same project?
}
}
I am very certain that it's a very fundamental thing I'm missing here, but what am I actually missing? The Class1 member "randomvariable" is public and so is the class and both classes are in the same project.
What do I have to do to fix this problem?
There are two problems:
Firstly, you're trying to assign a value to randomvariable from main, without there being an instance of Class1. This would be okay in an instance method, as randomvariable would be implicitly this.randomvariable - but this is a static method.
Secondly, you're trying to read the value from Class2.ranMethod, again without there being an instance of Class1 involved.
It's important that you understand what an instance variable is. It's a value associated with a particular instance of a class. So if you had a class called Person, you might have a variable called name. Now in Class2.ranMethod, you'd effectively be writing:
name.getSomething();
That makes no sense - firstly there's nothing associating this code with Person at all, and secondly it doesn't say which person is involved.
Likewise within the main method - there's no instance, so you haven't got the context.
Here's an alternative program which does work, so you can see the difference:
public class Person {
// In real code you should almost *never* have public variables
// like this. It would normally be private, and you'd expose
// a public getName() method. It might be final, too, with the value
// assigned in the constructor.
public String name;
public static void main(String[] args) {
Person x = new Person();
x.name = "Fred";
PersonPresenter.displayPerson(x);
}
}
class PersonPresenter {
// In a real system this would probably be an instance method
public static void displayPerson(Person person) {
System.out.println("I present to you: " + person.name);
}
}
As you can tell by the comments, this still isn't ideal code - but I wanted to stay fairly close to your original code.
However, this now works: main is trying to set the value of an instance variable for a particular instance, and likewise presentPerson is given a reference to an instance as a parameter, so it can find out the value of the name variable for that instance.
When you try to access randomvariable you have to specify where it lives. Since its a non-static class field, you need an instance of Class1 in order to have a randomvariable. For instance:
Class1 randomclass;
randomclass.randomvariable.getSomething();
If it were a static field instead, meaning that only one exists per class instead of one per instance, you could access it with the class name:
Class1.randomvariable.getSomething();
At present I have a class that is calling the static method of a different class. What I am trying to do however is have the static method change a variable of the calling class, is that possible?
Example code:
public class exClass {
private int aVariable;
public exClass() {
othClass.aMethod();
}
}
public class othClass {
static void aMethod() {
// stuff happens, preferably stuff that
// allows me to change exClass.aVariable
}
}
So what I would like to know is, if there is a way to access aVariable of the instance of exClass that is calling othClass. Other than using a return statement, obviously.
Not if aClass doesn't expose that variable. This is what encapsulation and information hiding are about: if the designer of the class makes a variable private, then only the component that owns it can modify or access it.
Of course, the dirty little secret in Java is that reflection can get you around any private restriction.
But you should not resort to that. You should design your classes appropriately and respect the designs of others.
You can pass this as a parameter to the second function.
public class exClass {
public int aVariable;
public exClass()
{
othClass.aMethod(this);
}
}
public class othClass{
static void aMethod(exClass x)
{
x.aVariable = 0; //or call a setter if you want to keep the member private
}
}
you should gave the static method in othClass the instance of exClass like othClass.aMethod(this), then you can change the variable of that instance, or make the variable static if you dont need an instance