I have a class for my GUI which I created using Swing UI Designer.
All the components were automatically made private but now I need output some text in a variable called consoleTextArea from outside of the UI.class
When I set consoleTextArea to public static I get an error saying "UI.form: Cannot bind: field is static: indeed.UI.consoleTextArea"
...
public static JTextArea consoleTextArea;
...
...
UI.consoleTextArea.setText("abc");
...
\src\indeed\UI.form: Cannot bind: field is static: indeed.UI.consoleTextArea
You can change the value of your label/textArea, through an instance of your UI class.
public class UI {
// ...
private TextArea consoleTextArea = new TextArea();
//
public void setTextInTextArea(String text) {
this.consoleTextArea.setText(text);
}
}
Having setters like this, you can manipulate your textArea from within a different class. This other class, however, must have access to the instance of UI, either instantiate it itself, or getting it passed as a parameter
public class OtherClass {
UI ui = new UI();
public void doSomething() {
ui.setTextInTextArea("New text");
}
}
or something like:
public class OtherClass {
public void doSomething(UI ui) {
ui.setTextInTextArea("New Text");
}
}
Instead of making the field public (not static public) you should rather add a method like this to your class:
public void setConsoleTextArea(String value) { consoleTextArea.setText(value); }
Then you can do
UI.setConsoleTextArea("abc");
without having to mess with the consoleTextArea field that is automatically generated.
Related
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 two .java files in the same package. I am planning on making the first .java file the underlying code and the second .java file the GUI swing interface.
My problem I encountered was when working on the GUI part of the project, I needed to access several methods from the .java file with the code. My .java file with the code is a like this:
package same;
public class HFSim extends ApplicationTemplate
{
private static class AppFrame extends ApplicationTemplate.AppFrame
{
public myMethodIWanttoUse()
{
//code
}
And in my GUI .java:
package same;
public class GUI extends JFrame
{
public GUI()
{
public void actionPerformed(ActionEvent e)
{
//this is where I want to use the method from above
Is there a way to get that method to be used in the GUI portion? Or is there a better way to approach this problem? thanks in advance.
You have multiple solutions to your problem. The first question you should answer is how these methods you need to call qualify themselves.
Are they utility methods? (They don't require an instance of an object to work on)
Are they attached to a single instance of an object?
Do you need to call methods of a specific object more than just methods?
You can either:
Declare them static and call them, eg HFSim.AppFrame.myMethoIWanttoUse();
Declare a static instance of the object containing them, eg
public class HFSim extends ApplicationTemplate {
public static final AppFrame appFrame = new AppFrame();
...
}
public class GUI extends JFrame {
public GUI() {
public void actionPerformed(ActionEvent e) {
HFSim.appFrame.myMethodIWanttoUse();
}
}
}
Pass the instance of the object to the other one:
public class GUI extends JFrame {
private final HFSim.AppFrame appFrame;
public GUI(HFSim.AppFrame appFrame) { this.appFrame = appFrame; }
public void actionPerformed(ActionEvent e) {
appFrame.myMethodIWanttoUse();
}
}
Make methodIWantToUse() static by replacing
public myMethodIWanttoUse()
with
public static myMethodIWanttoUse()
Secondly, make AppFrame marked as public instead of private.
Then just call you method like this HFSim.AppFrame.myMethodIWantToUse().
Edit:
Alternatively, you don't have to make your method static. Just add this in your GUI code:
HFSim.AppFrame frame = new HFSim.AppFrame();
frame.myMethodIWantToUse();
Still, no matter what, you have to make AppFrame be public.
So I have a MainWindow.java that creates the window with all the controls and things. I put a menubar object on the window, one of the options in the menubar is make the program a server. So here's the main window looks like this:
public class MainWindow extends javax.swing.JFrame {
//all code including menubar click action handler
//Server.start()
}
When you click the option, it goes into the Server.java class and starts the server. Here's the skeleton of that class:
public class Server {
public static void start(String port) {
try {
startServer(Integer.parseInt(port));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void startServer(int PORT) throws Exception {
...
}
private static class ClientListenThread extends Thread {
public ClientListenThread(Socket socket, int ClientNumber){
...
}
public void run() {
...
}
}
private static class ServerSendThread extends Thread {
public ServerSendThread(Socket socket) {
...
}
public void run() {
...
}
}
}
The problem now is that once it gets inside the Server class, it listens for connections and connects fine but I just can't go back to the MainWindow class. It stays within the Server class. I can't even call the MainWindow functions by doing MainWindow.function() because it says
Cannot make a static reference to the non-static method function() from the type MainWindow
I even tried putting all of the Server class code into the MainWindow class or just above it but Java didn't like that and said it wanted it in a separate file.
How exactly do I reference MainWindow functions from within the Server class? Or is there a better way of going about this?
You need to either create an instance of the MainWindow class using for instance MainWindow m = new MainWindow() and then calling the function as m.function(), or declare your function as static.
Static means that you can call a function without creating an instance of the object. This is why you get the error, since your function is not static, so it requires an instance of the object to be called.
You'll also want to make sure that the MainWindow class is imported into the Server class.
Given two classes, creating an object of each class in one another results in StackOverflow Exception. It is a JAVA project btw.
There are multiple classes in my projects and for using the other classes, I thought i would create objects of the other class and use it.
Say i have class Main and class GUI. I have created object of GUI in MAIN and initialized it. Similarly i have created an object of MAIN in GUI and initialized it.
Now this gives me a Stack Overflow Exception as the the constructor calls are going deep into recursion.
How do i go about it?
One possible solution i can think of is making variables and methods of one class STATIC.
Any other solution? Please suggest.
You should be passing an instance of one of you classes into the constructor of the other class.
public class Main {
private final GUI gui;
Main() {
gui = new GUI(this);
}
}
public class GUI {
private final Main main;
public GUI(Main main) {
this.main = main;
}
}
You could also use setters instead of constructors. I don't like this option as much, because you lose the ability to make your variables final.
public class Main {
private GUI gui;
Main() {
}
public void setGui(GUI gui) {
this.gui = gui;
}
}
public class GUI {
private Main main;
public GUI() {
}
public void setMain(Main main) {
this.main = main;
}
}
public static void main(String[] args) {
Main main = new Main();
GUI gui = new GUI();
main.setGui(gui);
gui.setMain(main);
}
Singleton ? (if it works for your app )
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.