Reference a method from a different Java file - java

I'm new to Java programming and am facing a (most likely) easy problem that I don't seem to be able to get across nor understand.
I have three different java files, one where I create an interface (SimulatorGui.java), other where I am creating a panel to use on the jTabbedPanel created in the interface (CollisionPanel.java - CollisionPanel class) and a third one, where I run a code that will create the output needed (Collision.java - Colision class).
In the Collision.java main method, I am doing the following:
public static void main (String[] args) {
//<editor-fold defaultstate="collapsed" desc="Simulation start procedures">
Tally statC = new Tally ("Statistics on collisions");
Collision col = new Collision (100, 50);
col.simulateRuns (100, new MRG32k3a(), statC);
//</editor-fold>
new SimulatorGUI().setVisible(true);
CollisionPanel update = new CollisionPanel();
update.updatepanel();
The first block, will create the desired output. I then want to send that output to the updatepanel! I am not passing any arguments to the method as I am still trying to debug this. updatepanel method is created in the file CollisionPanel as following:
public void updatepanel(){
System.out.println ("debug");
jTextArea1.setText("update\n");
}
What happens then is that when I run the Collision.java file it will output the "debug" text but won't set the text to the jTextArea1 (append doesn't work aswell). I then created a button to try and do so and in that case it works. In CollisionPanel.java:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
updatepanel();
}
This does the trick! I've searched and tried different things but can't seem to understand why this won't work.
Thanks in advance for your help, hope I've made the problem clear!

Okay I think I've eventually got the problem, and it is because of the IDE, you see in your main method you initiate a new CollisionPanel, which is wrong, netbeans has already added and initiated that panel in the SimulatorGUI, so now what you need to do is add a get method in the SimulatorGUI to get the initiated panel, then call the update method on that panel.
So add this to SimulatorGUI:
public CollisionPanel getCollisionPanel1() {
return collisionPanel1;
}
replace your old updatePanel() method with:
void updatepanel(String str) {
System.out.println ("debug");
jTextArea1.setText(str);
// jTextArea1.revalidate();
jLabel1.setText("test");
}
after that change your main too look like this:
SimulatorGUI simulatorGUI = new SimulatorGUI();
simulatorGUI.setVisible(true);
CollisionPanel cp=simulatorGUI.getCollisionPanel1();
cp.updatepanel("Hi");
and dont forget to remove the old updatePanel() method call from your CollisionPanel constructor, because now you can simply call cp.updatePanel("text here"); in your SimulatorGUI class instead of calling it only in the constructor.
I hope this is easy to grasp, if you're unsure let me know

Where do you add your CollisionPanel to the main GUI? I fear that this is your problem, and that you need to do this for your code to work. In fact where do any of your three classes get a reference to the others? For different classes to work in a program, there must be some communication between them. Understand that if you create a CollisionPanel object inside the GUI, and create another CollisionPanel object inside of the main method, calling a method on one object will have no effect on the other since they are two completely distinct entities.
For example, this code:
new SimulatorGUI().setVisible(true);
CollisionPanel update = new CollisionPanel();
update.updatepanel();
It appears that you are in fact calling updatePanel() on a CollisionPanel, but it's not on any CollisionPanel that is visualized in your GUI.
Consider giving SimulatorGUI a method that allows one to pass the CollisionPanel into it so that it can use it. This may in fact be a constructor parameter:
CollisionPanel update = new CollisionPanel();
SimulatorGUI simulatorGUI = new SimulatorGUI(update);
update.updatePanel();
Meaning SimulatorGUI's constructor would have to look something like:
public SimulatorGUI(CollisionPanel update) {
this.update = update;
// add update to GUI somewhere
}

There are three different levels when developping a GUI:
The view: the graphical component
The Model: the code that you run
The controller: checks if are update on the model in order to refresh the view.
So When you first start your program, the view will have the value assigned in the code; for instance say you created your JTextArea with the initial value type here. The view will show the JTextArea with the text type here.
When a change is made to the model, the view is not aware of it, it is job of the controller to check for update on the model and then refresh the view.
So this:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
updatepanel();
}
Will generate an event that say a property has been modify. So the controller will update the view.
Other than that, the change will not appear on the view.
Hope this helps..

Related

Java wait for method to return object

I am making a library where an application can use it to capture a selection of a screen and convert it to an image, like Gyazo.
This library is not the application itself, but only the tool that returns the File or BufferedImage object to the application.
I want the application to be simple as this:
Bootstrap b = new Boostrap(new GifCapturer());
b.beginCapture(); // user selects an area
File file = b.getFile();
But how can I make the application wait till the library returns the object? as you see the beginCapture method should activate the JFrame where the user will select an area to capture.
Do I need to sleep the thread? or use listeners design?
The beginCapture method starts a jframe window, where the user is able to select an area of the screen. Once selected, the library will convert the selected area to an object and set it as a local variable. So when you will use getFile it ill return the captured image. But the thing is, i need to make sure that the image was selected before getFile call gets executed, and wait instead but im not sure how.
Sorry if the question is not detailed, im on phone.
Please let me know if you need more information.
Implement a listener, that is invoked as soon the selection is ready. Put your File file = b.getFile(); code into the listener.
The code of your JFrame would be necessary to give a more detailed answer.
I have decided to use a Listener with a own built listener class, and interface.
Create an interface which you will use to get the data, or that will get know when the listener gets called, like this in my case:
public static void main(String[] args) throws AWTException {
Bootstrap b = new Bootstrap(new GifCapturer());
b.beginCapture(new ScreenCaptureCallback() {
#Override
public void captureEnded(File file) {
System.out.println("done!");
}
});
}

Call to jFrame from jInternalFrame does not work

I have a main jFrame HomePage.java and many other classes which extend javax.swing.JInternalFrame. One of the classes (JInternalFrame) is Login.java. Now I check whether the password is correct in Login.java and if the password is correct, I load success.java. Now the problem arises when I have to load the success.java page.
I have a function in the HomePage.java whose purpose is to remove all internal frames and load success.java class. The function is as follows :-
public void LogIn(){
jDesktopPane1.removeAll();
System.out.println("Pos 2");
success frame = new success();
frame.setVisible(true);
jDesktopPane1.add(frame);
setContentPane(jDesktopPane1);
try {
frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}
I call the function in the Login.java page as follows :-
System.out.println("Pos 1 ");
(new HomePage()).LogIn();
The logic does not work. But, I receive the output as
Pos 1
Pos 2
which shows that the program flow was correct. I do not get any error also. Another weird factor is that when I calthe same LogIn() function from the menu in the jFrame itself, I get the desired output. Please solve my dilemma. Any help will surely be appreciated!
This code:
System.out.println("Pos 1 ");
(new HomePage()).LogIn();
Creates a new HomePage object and calls a method on it. Oh you are certainly calling the correct method, and it's going a HomePage instance, but it's not the correct HomePage instance, not the one that's displayed, because you've created a new one.
Short term solution: get a valid reference to the displayed HomePage instance and call your method on it. You could get it by passing it into the class that needs it as a constructor or method parameter, or you could use SwingUtilities.getWindowAncestor(...).
i.e.,
Window window = SwingUtilities.getWindowAncestor(Login.this);
if (window instanceof HomePage) {
HomePage validHomePageRef = (HomePage) window;
validHomePageRef.logIn();
}
Long term solution: don't create spaghetti code with GUI objects changing behaviors of other GUI objects, but instead refactor your code a la MVC or one of its variants, so the GUI can change the model and the other GUI objects can be notified of these changes via listeners and respond if they want.

Java - passing values through frames

I need to ask a small question because its irritating me.
How do i pass one vale from one frame to another frame in Java?
Below i have written a small script that is supposed to return the value but i dont quite know how to access it in the other frame.
Here is the code that is suppose to return the current value in a JcomboBox as a string into the other frame:
public String getUser(String user)
{
user = (String)jComboBox1.getSelectedItem().toString();
return user;
}
The way i thought it would work is to call a new instance of that class into the other frame (the classes name is editUser) so here is what i thought i would need to do.
public editPass()
{
initComponents();
editUser name = new editUser();
String test = name.getUser();
}
Thanks in advance for any advice.
The problem is that with doing this: editUser name = new editUser() is that you are creating a new instance (besides the fact that class names should start with upper case as per convention). This causes you to loose any data since you are now referencing a new object.
If you need to access data from the previous frame, what you would need to do would be to either:
Create a new object with all the relevant data and pass it to the next frame OR
Pass the current frame to the next frame. This will allow the new frame to be able to reference the previous one.
As a side note, the Card Layout might be relevant to what you are trying to achieve.
EDIT:
As per your comment question:
Assuming you have an editUser frame, say we call it frame1 and you populate all the data you need.
Then, the user presses Next, or something similar which causes him/her to go to the next frame, thus frame1 will either be hidden or non existant any more, depending on your implementation.
Let us call the second frame frame2. Now, in frame2 you need to access details stored in frame1. Doing like so: editUser name = new editUser(); will cause frame2 to create a new instance of frame1, thus meaning that you have created a new frame with empty values. Calling name.getUser() should not yield anything.
When I mentioned create an object with the relevant data I meant that, if you are editing user values, you could create an object which would have for instance all the information which was edited. So it could have fields like userId, originalUserName, newUserName, etc.
One the user presses Next in your frame1, you could create and populate this object and use it to transfer data from one frame to the next. In this case, the object you would be creating would be known as a Data Transfer Object (DTO).
So, the constructor of your second frame would look something like so:
public editPass(UserEditDTO userEditDTO)
{
initComponents();
String test = userEditDTO.getNewUserName(); //gets the new username the user has provided.
}
And in your editUser class, just before creating a new instance of editPass, you would do something like so:
...
UserEditDTO uEDTO = new UserEditDTO();
uEDTO = ... //set all the relevant fields here
new editPass(uEDTO).setVisible(true);
...
Alternatively, you can pass a reference to frame1 instead of a DTO. This approach is simpler. So your constructor for editPass would look like this:
public editPass(editUser editUser)
{
initComponents();
String test = editUser.getUser();
}
With your editUser code looking like so:
...
new editPass(this).setVisible(true);
...

Eclipse RCP: Custom console

I am trying to create a console that would work as a shell for a custom programming language. It would be very similar to the pydev interactive console.
Currently, my RCP uses the basic TextConsole and is connected to the shell via pipes so it just displays whatever the shell displays and if the user enters anything in the RCP console, the same is written in the shell.
I want to be able to do a bit more such as move the caret position, add events for up and down arrow keys etc. I believe to do that I need to add a StyledText widget to the console which is done via the ConsoleViewer.
So my question is, that is there any way for me to either override the TextConsole's ConsoleViewer or if I were to extend TextConsole and create my own, then how do I link it with the launch configuration (the one that connects the shell via pipes)?
Also, to get the current default console I use DebugUITools.getConsole(process).
I'm sorry if I haven't put all the information needed; it is a bit difficult to explain. I am happy to add more information.
An idea...
From what I understand I can create a TextConsolePage from the TextConsole using createPage(ConsoleView). Once I have the page I can set the viewer via setViewer(viewer). Here I thought if I create my own viewer (which will have the appropriate stylewidget) then that could be a lead. The only problem is that the viewer needs a Composite and I can't seem to figure out where to get that from.
Why don't you just follow what PyDev does (if you're able to cope with the EPL license)?
The relevant code may be found at:
https://github.com/aptana/Pydev/tree/ad4fd3512c899b73264e4ee981be0c4b69ed5b27/plugins/org.python.pydev/src_dltk_console
https://github.com/aptana/Pydev/tree/ad4fd3512c899b73264e4ee981be0c4b69ed5b27/plugins/org.python.pydev.debug/src_console
So I thought I would answer this myself as I was finally able to accomplish the console. It still is a working prototype but I guess as you keep adding things, you can clean up the code more and more. For my current purposes this is how it worked.
If you want the short version, then I basically mimicked the ProcessConsole provided by Eclipse as that is what I needed: a console in which I can connect a process but since the ProcessConsole is internal, I like to avoid extending those classes.
Following is an outline of the classes I used to achieve interaction with my console. I am not going to give the pretext as to where MyConsole was created. Basically, instead of using DebugUITools.getConsole(myProcess), I used my own myProcess.getConsole() method. MyProcess extends RuntimeProcess.
class MyConsole extends IOConsole {
private IOConsoleInputStream fInput;
private IOConsoleOutputStream fOutput;
private IStreamsProxy fStreamsProxy;
private ConsoleHistory history;
//This is to remember the caret position after the prompt
private int caretAtPrompt;
/* in the console so when you need to replace the command on up and down
* arrow keys you have the position.
* I just did a caretAtPrompt += String.Length wherever string was
* appended to the console. Mainly in the streamlistener and
* InputJob unless you specifically output something to the output
* stream.
*/
//In the constructor you assign all the above fields. Below are some
//to point out.
//fInput = getInputStream();
// fStreamsProxy = process.getStreamsProxy();
// fOutput = newOutputStream();
//We must override the following method to get access to the caret
#Override
public IPageBookViewPage createPage(IConsoleView view) {
return new MyConsolePage(this, view);
}
//After this I followed the ProcessConsole and added the
//InputJob and StreamListener
//defined in there.
}
class MyConsolePage extends TextConsolePage {
//Not much in this class, just override the createViewer
// to return MyConsoleViewer
}
class MyConsoleViewer extends TextConsoleViewer {
//This is the most important class and most of the work is done here
//Again I basically copied everything from IOConsoleViewer and then
//updated whatever I needed
//I added a VerifyKeyListener for the up and down arrow
//keys for the console history
MyConsoleViewer (Composite parent, MyConsole console) {
//I have omitted a lot of code as it was too much to put up,
//just highlighted a few
getTextWidget().addVerifyKeyListener(new MyKeyChecker());
}
class MyKeyChecker implements VerifyKeyListener {...}
}
This is the code for ProcessConsole.
This is the code for IOConsoleViewer.
The ConsoleHistory class I created just had a doubly linked string list to save all the commands the user entered. Quite a simple class to create.
Once you look at the Eclipse classes (ProcessConsole and IOConsoleViewer) it is actually all quite self explanatory. I haven't put in much code here because there is quite a bit. But hopefully this gives some direction as I was completely lost when I started.
I am happy to answer questions though and add more specific code if anyone asks.

Create subclasses of parent class from file

I'm trying to create a menu screen, and I want to be able to create it, and any further permutations of it dynamically. I've created a MenuItem helper class to handle the menu items that show up, and it reads the name, image, and set the next state (something that is handled later). What I want to know is, how can I create the specific following Screens (they'll all be some subclass of my Screen class)?
What is the most efficient method to pass specific objects into the menuItems? Do I need to pre-create each possible Screen and then just read back in the serialized form of it, or can I create them dynamically. I'd hoped to be able to do something as simple as reading in a literal string "new SubClass(...)" and act off that, but I don't know how to go about that. Any other suggestions would be great!
If I understand correctly, what you want is a mechanism that reads a String command from a text file, and based on this command, displays a screen.
So, extract the interface of the "display screen" command into an interface. For example:
public interface ScreenDisplayer {
void displayScreen(Screen mainScreen);
}
Then build a Map<String, ScreenDisplayer>:
map.put("screen1", new ScreenDisplayer() {
#Override
void displayScreen(Screen mainScreen) {
// TODO display screen 1
});
// same for all the other commands
And when a "menu item" is clicked, get the DisplayScreen from the map and call it:
String command = selectedMenuItem.getCommand();
ScreenDisplayer displayer = map.get(command);
displayer.displayScreen(mainScreen);

Categories

Resources