Managing the function main - java

I created a class A that reads a text file and alters some lines within the text, and the code is written in main() of this class. I also created another class B that has a Frame, the Frame contains a list of text files of a directory and a button. What I don't know how to do is this: When I click on the selected item on the list and click the button, the function main is called and the selected item is being read by main().
Any suggestion is welcomed and thanks in advance.

When you have code in the static main method, you have a non-object oriented code block, one that won't easily be used by other object oriented-compliant portions of your program. The best solution here is to get all code but the minimal out of main and create a true OOP-compliant class, one that can be more easily used by your other classes.
Your other issue is the mixing of your text-processing code with your GUI code, and this may require further fixing, especially if the text-processing code takes a while to complete or is a CPU hog. If so, you'll need to take care to do the text-processing in a thread that is background to the GUI thread, and again, this is much more easily performed if the text-processing code is in a well-behaved OOP class.

The main method is just like any other method, you call it the same way.
class A {
public static void main(String... args) {
String filename = args[0];
}
}
class B {
public void onFilename(String filename) {
A.main(filename);
}
}
You might want to use a background thread instead of locking up the GUI while it is processing. ;)

Related

How and when to declare a Main Method

This may seem like a stupid queestion to most of you, but I have been learning Java using BlueJ, and BlueJ is created for learning, and as such Main Methods are not necessary given the BlueJ extensions provided by my University.
Therefore, now that I am playing around in both NetBeans and IntelliJ - I really want to get a good idea of when to declare a Main Method.
I know the Main method is the entry point of a package when it is compiled and run. But that is the extent of my knowledge.
If I am to build some apps in a full blown IDE, should I place all of my Class methods within a Main Method? Should the Main method be seperate from all others? Do I declare instance Variables within the Main Method?
Are there any good sites, or tutorial materials available that can help me structure my BlueJ Java knowledge into an IDE that requires a Main Method?
Thanks
Ok.
Main method is an entry point to your application.
If you watch any Java related tutorial, you'll probably see something like this.
public class HelloWorld {
public static void main(String[] args) {
// Prints "Hello, World" to the terminal window.
System.out.println("Hello, World");
}
}
This has been taken from Oracle's website.
When working with IntelliJ, you'll be presented with a package main on the top, or something else.
You see. Java unlike some other languages distinguish between namespaces using those packages. Think of them as a little packages full of Java classes that you can reuse.
For example, if you look at Log4J's repo => here, all these folders are essentially packages.
That way you can have many packages, and a single file that will trigger your main method, and start everything else.
That's how it's usually done.
But if you really want to learn Java from scratch. My suggestion is go to YouTube. Derek has done some marvelous job with his tutorials.
Best of luck.
While technically you can have more than one main method, for most use cases you only need one.
You should define it where it makes sense to do so in some "central" class responsible for bootstrapping your application and getting everything going.
The main method is static though so it can't access your class' instance. Typically this is how you'd get around this.
class TicTacToe {
public void theEntryPointToYourApplication() {
// ...
}
public static void main(String[] args) {
// This doesn't necessarily have to be the same class where you
// defined your main method
TicTacToe ticTacToe = new TicTacToe();
ticTacToe.theEntryPointToYourApplication();
}
}
This is just a small example though there are many ways and different approaches depending on your specific use case and needs.
Personally I have never used BlueJ.I've always been a netbeans fan.But the answer to your question is a general rule that most of the Object Oriented Programming Languages follow.You know that main method is the entry point of a package when it is compiled and run.Let me explain it in simple language.
Consider a soccer game.Assume that the field is the main method.The players are different functions.You are free to define any number of functions, but only 22 functions are called in the field.The whole game is controlled and played by these 22 functions only.So what do you learn from this?
We learn that java is only concerned with what is present in its main method just like the fans sitting in the stadium are only concerned with the 22 players who are currently playing.So if a programmer is writing a small program,normally the whole logic goes into the main method.But if its a large program,the program is distributed into various modules/functions and then these functions are called in the main method so that they get executed.

How to correctly implement communication between Java classes

I'm a beginner in Java programming and I'm currently working on an app with more complex class structure and a GUI. This might be a stupid questions, but it is very hard to google, so I'm asking here.
I have a main class, looking like this:
package app;
public class App {
private FirstClass fc;
private SecondClass sc;
public App () {
fc = new FirstClass ();
sc = new SecondClass ();
// ... code continues ...
}
}
Say the SecondClass is defined outside of this .java file (like GUI forms are). Is there a way for me to access the "fc" instance (or other member variables of the App instance) from the "sc" instance (without passing the "this" pointer)? Something like:
class SecondClass {
public void someMethod() {
getWhoeverCreatedThisInstance().fc.getSomeData();
// ... code continues ...
}
}
And if not, what am I doing wrong? Should I design this differently? Maybe setting the "fc" as static? But what if I want more of my app's classes to communicate with each other, should I make them all static? What would be the point of having something non-static then? I could pass the "this" pointer of "App" or "fc" instance in the constructor of "SecondClass", but that solution just seems non-elegant when the number of classes that need this behavior rises.
Any ideas? Thanks in advance!
My suggestion is to implement a callback system with interfaces. Each of your classes communicating with each other should implement these.
The classes should Register to the creating class.
Then they can call a method in the creating class which invokes the interface method of each registered class and passed the data this way.
This SO answer might help
https://stackoverflow.com/a/18279545
If you want to develop GUI applications, you should really get into the basic concepts. This can be very time-consuming, but it is necessary, otherwise you will encouter strange behaviour. I will just give you a basic understanding to answer your question.
You think of simple console applications, where you usually have a single thread and passing around objects is valid. With multiple threads, this is fatal, even with static variables. Each variable or object can be modified concurrently and the other thread may not be able to 'see' the changes in time. This is a complex matter, since there are also caches and separate stacks for each thread. In short, fc may not always be synchronized in App and sc, therefore reads and writes may be inconsistent.
What to do now? Learn the concepts of GUI programming. Often you do not even have to share objects for simple things. If a GUI control triggers an action, use a Listener, look here. If you want to access a database for example, then just make a new connection object for each request or button click, whatever. This is simple to start, add complexity later.
A simple variant to share objects is to use the synchronized keyword, which ensures that a method or a field is only accessed by one thread at a time. Here is an example. Also look at thread-safe data structures provided by Java (java.util.concurrent).
For advanced purposes you would have a separate thread and you would connect them with Sockets to pass messages or data.

Java, Netbeans and separation of concerns

I am new to Java and Netbeans, and want to write a Swing project to learn by.
Naturally I want to separate the "guts" of the code from the GUI class.
How should I go about it, best practice ?
Should I:
Use public static void main(String[] args) in the GUI class. Then
create an instance of a "controller". Calling controller functions
via GUI events (passing only data) ?
Use public static void main(String[] args) in the "controller",
and pass an instance of the controller to the GUI class ?
Create instances, or use classes statically ?
And what of this invokeLater business ?
[ some little code samples would be lovely ]
Thanks.
Anthony.
Three: Put main() in its own class and intitialize all objects as needed.
I'd create a Main class or other entry class that contains main. This would be responsible for preparing the system, initialising common library elements and general house keeping.
As to which element needs to be "started" will depend on the structure of your code and your implementation of the MCV

According to basic oop conventions, should the menu code be in the main method or in a class?

I'm a student and I'm new to Java, this assignment I am doing is the first assignment I have to do that has to strictly follow oop conventions. So this may be a newb question. When coding a menu, would it be appropriate to put the menu code in the main method or should it be in a class and instantiated along with everything else?
EDIT:
The menu menu is a simple command line menu that is inputed with numbers, no gui. Not that far yet.
If you want to strictly follow the OOP convention you could have your own class like
abstract class MenuItem {
int index;
protected MenuItem(int index) {
this.index = index;
}
abstract void action();
}
class ExitMenuItem {
ExitMenuItem() {
super(3); // the index value of the menu item
}
void action() {
System.exit(0);
}
}
So that you can have a subclass specific for every menu item that has its behavior.
Then you could have a menu container, something like:
class Menu {
ArrayList<MenuItem> items;
void executeAction(String input) {
..
}
}
that should understand which voice has been chosen according to the stdin input and execute it. Of course you can enrich everything by having a default text for every menu item and whatever. Then in your main method you just instantiate the menu and take care of forwarding stdin input to it.
Mind that this is usually overkill in a simple menu but if you want to understand OOP then it's a nice way to go.
For a Object-Oriented approach, you should create the menu in the specific class. Main method is a legacy of Procedural/Imperative programming languages. Main method should just run the main thread.
It depends. That's usually the worst answer one can provide, but unfortunately, it fits perfectly.
You haven't provided the full requirements so it is a little difficult to guess what you are intending. Is this menu specific to a single class? Can it be run multiple times? Should it be able to be run in parallel?
Or rather, is this menu just an entry point into the actual program? ex: press 1 to login, press 2 to display something on screen, press 3 for ....
The reason I am giving you these questions is because they will shape the structure of your code. In the first case, if they are menus related specifically to a class and can be run from multiple locations in the code at multiple points, then it would make sense that the belong within the class structure itself (non static).
However, if the menu is purely an entry point into the application, it would make sense to either put them in the main() section of the code, or code another static method called menu() for clarity. But realistically, the menu() method would only get called from the main.
The next thing to ask yourself is how you plan to validate the responses from the menu selection. Do you need complicated/involved code? Does it make more sense for the validation routines to be part of the main method or have their own methods? Does it make more sense to have member variables to communicate between method class to validate, etc?
Keep in mind that static methods can be called without instantiating the class. That being said, a static main() method or static menu() method still remain within the class itself, and are part of OOP design.
Ask yourself this - if putting codes that prints menu in the main method, how do I handle printing multiple times?
If putting codes into methods in the same class as the main and I need to print menu somewhere else probably in another main class, how do I handle that?
Eventually, you will have a class that handles code dealing with displaying of menu, and the main class would only be calling on methods of that class. :)
Probably there are different tastes to this, and a good answer might also depend on what your app is doing.
First, for a small application I wouldn't mind having the menu in the main class.
But then for nice structure, it is a good idea to have a class that is responsible for printing the line-based menu and then of course also for reading the user input and invoking the action the user asks for. I think a good idea would be to call such a class Controller or Dispatcher. This class would be a singleton. Further I would think it's a good idea
to have a method displayMenu and dispatch. Both would be called from the constructor consecutively.
How dispatch is then calling the appriopriate action will depend on the rest of your app.
Some people don't like this style, as your main routine will probably have declarations only.

Can someone explain how to setText from a static using my example?

First I would like to say that I have only worked with java for 1 month now. This is probly a pretty simple question. I searched and the classic fruit example did not make any sense to me. I spent hours looking at it and trying to figure out how to apply this to make it work. It does not make any sense to me because everyone explains how to get and set a property with 2 lines of code and no structure statements. I would really appreciate a breakdown in how to talk to non-static from static.
I would like to setText in text box in my OBD2nerForm class from a separate and static class.
public class OBD2nerForm extends java.awt.Frame {
/** Creates new form OBD2nerForm */
public OBD2nerForm() {
initComponents();
} ....................................
public String setText(String text){
this.jFormattedTextField1.setText(text);
}
I think I have a static reference to this instance of the form defined here..
public class Status {
public static OBD2nerForm form = new OBD2nerForm();
it is called from my main like this
public class obd2ner {
public static void main(String[] args) throws IOException {
Status.form.main(args);
Then when I try to call it.. Status.form.getText gives me the initial values when the form is created. When I setText, it does not change the one on the screen.
I am just displaying this to keep it simple. There are many other parts going on. I have a static monitor on a serial port and I want it to grab the next data to be sent from the text box and then increment it.
I just don't understand how to use a getter and a setter on a non-static. It's not quite doing what I need it to do. It seems like I am seeing one instance on my screen and it is using a new instance to perform the getting and setting.
I tried this as per an answer I received, but it did not work...
public class OBD2nerForm extends java.awt.Frame {
String X = "";
//Trying out the runnable method of incrementing the code
public String getNewScannerValueRunnable(){
Runnable doWorkRunnable = new Runnable() {
#Override
public void run() {
Status.form.getNewRotatingValue()
;}
};
SwingUtilities.invokeAndWait(doWorkRunnable);
return X;
}
I could really use some other suggestions. i just don't understand what has to happen here.
Your form is being created fine, and there's just one reference to it, and it's ending up in that static variable. All is well up to that point.
There's a 'secret' of Swing you need to be aware of: You cannot (visibly) change the properties of GUI objects from any thread other than the Swing thread, aka the Event Dispatching Thread.
The trick to doing it anyway is to pass the property-changing code as a Runnable to either of SwingUtilities.invokeAndWait() or SwingUtilities.invokeLater().
EDIT:
OK, let's back up. Your form is AWT based, not Swing based, so I'm afraid my advice on using SwingUtilities would probably not have helped you, even if you had implemented it correctly. I'll try to give more specific hints this time.
You've created a class OBD2nerForm that's an AWT form. That class has a constructor which calls initComponents to set up some GUI components on the screen.
The class also has a method called setText that will put its argument text into one of the fields on the form. That method is an instance method, i.e. it's not "static", as you'd call it.
You have another class, Status with a class field form. The initializer for form calls the constructor for OBD2nerForm. That will create an instance of the form and store it in form; but I haven't seen a show() or setVisible() call being made to the form to actually display it.
Here are the first signs of trouble:
public class obd2ner {
public static void main(String[] args) throws IOException {
Status.form.main(args);
Class names (like obd2ner) should start with capital letters; but that's a matter of style and convention, it's not what's causing you problems. Following the conventions helps other people read and debug your code, though.
The bigger problem is obd2ner.main() calling your form's main(). That could be made to work, but it's usually a sign that you're doing something wrong.
While nothing stops you from coding static main methods into as many of your classes as you want, only one of those main's can be started from the outside, i.e. when you run your application. The first main is essentially the 'boss' method for your program.
The "first main" usually instantiates and initializes a few objects. In a non-GUI application, main() may then start up a loop or some other control structure, wherein it will then orchestrate the actions of the other objects. In a GUI application, main() will usually just instantiate and then show the GUI, and then end; once the GUI is visible, all further program activity is triggered by actions the user performs on the GUI.
Without seeing your code, I'm guessing that Obd2nerForm.main() also instantiates Obd2nerForm, and shows it. So you probably indeed have one instantiated but invisible form hanging off Status.form and another one instantiated, visible and referenced from some variable in Obd2nerForm. If you want to influence that GUI, you need to make a reference to that form accessible.
Probably the simplest would be:
In Obd2nerForm, declare a public static Obd2nerForm form, and in Obd2nerForm.main, right after you call the constructor, copy the reference to the form into that variable. From then on, you can access the form and its methods using e.g. Obd2nerForm.form.setText().
A reminder, though: You seem to have two main()s, and this needs fixing. All the stuff that should be done at the beginning of the app's lifetime needs to be in one of those mains, not several.
Finally, look at this method call:
Status.form.main(args);
That's the syntax for calling a method on a particular instance. But Obd2nerForm.main is a class method (what you call "static"), and so there isn't "a particular one" to call, it's always just the one that belongs to the class itself. That's why the syntax to call a class method is something like
Obd2nerForm.main(args);
The compiler lets you get away with the way you wrote it, but it's not how it's usually done, and indicates some confusion.
There... I hope that gets you a little further along. If you still have problems, please post a more complete code sample to PasteBin and I'll take a look!

Categories

Resources