My main class is called MainClass and it has the following code in it:
Startup startup = new Startup();
while (!startup.isDoneWelcoming()){
System.out.print("Waiting for welcoming to finish."+br);
try{Thread.sleep(5000);}catch(Exception waitEx){System.out.print(waitEx+br);}
}
And the value it checks for is from another class called Startup which has this code:
private boolean doneWelcoming=false;
void openWelcomeScreen(){
//irrelevant code...
//a welcome screen is displayed and when "get started" button is pressed
//it opens a new window from the Tutorial class
WelcomeScreen welcomeScreen = new WelcomeScreen();
welcomeScreen.openWelcomeScreen();
//irrelevant code...
}
void setWelcomeStatus(){
System.out.print("Boolean \"doneWelcoming\" is true."+br);
doneWelcoming=true;
}
public boolean isDoneWelcoming(){
System.out.print("Boolean \"doneWelcoming\" value returned as: "+doneWelcoming+br);
return doneWelcoming;
}
The WelcomeScreen class extends from Startup and has this code that initiates the method createTutorialWindow inside the Tutorial class:
void createTutorialWindow(){
//ActionListener detects when the button is pressed and it does this...
Tutorial startTutorial = new Tutorial();
startTutorial.createTutorialWindow();
}
The setWelcomeStatus method is called from another class called Tutorial which extends from Startup. There I have a button and when pressed it does this:
setWelcomeStatus();
My problem is that I see this in my console:
Waiting for welcoming to finish.
Button clicked. Will return welcoming process as complete.
Boolean "doneWelcoming" is true.
Boolean "doneWelcoming" value returned as: false
Which means that doneWelcoming's value does change but it doesn't get returned as true to the original class and so my loop never stops. What should I change to fix this?
EDIT: Added code for WelcomeScreen class in both Startup and the class itself.
NOTE: It is rather obvious that a lot of instances of classes are involved, so it get a little complicated. Thank you for your help.
After reading #Hovercraft Full Of Eels's comment again I figured that the problem lied in my inheritance and he was right. I removed the extends from both my classes: WelcomeScreen and Tutorial and then made small methods to return values from one class to another while using a single instance for each class, like so:
In the Startup I did:
private WelcomeScreen welcomeScreen = new WelcomeScreen();
public boolean isDoneWelcoming(){
System.out.print("Boolean \"doneWelcoming\" value returned as: "+doneWelcoming+br);
return welcomeScreen.returnToStartup();
}
In WelcomeScreen I added:
private Tutorial startTutorial = new Tutorial();
boolean returnToStartup(){
return startTutorial.returnToWelcome();
}
In Tutorial I added:
buttonClicked=false;
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
buttonClicked = true;
}
});
//and as a separate boolean
boolean returnToWelcome() {
while (!letsgoClicked) {
return false;
}
return true;
}
Related
To be clear, the several similar-appearing entries here DO NOT actually talk about building a menu dynamically since all their object name choices and such are already in their code as fixed strings already written in the source code; all they're doing is waiting until run-time to create their statically designed menu items. Here are two entries I found like that: One and Two. The concerns there merely had to do with the trivial (but vital) task of refreshing the display, NOT with anything like actual dynamic creation of content.
What I want to do, in sharp contrast, is to truly add dynamically: I want the user to be able to choose to add items to a sub-menu that they can then later select and have take action within the application.
Let's take the case of simply adding an integer value to a menu and then being able to select it later, similar to what can easily be done with a combo-box but instead done with a menu.
The problem isn't the syntax pertaining to defining, for example, a MenuListener that will point to a method that knows how to act, that's not the problem. Rather, I just don't know enough about the dynamic NAMING SPACE, and how to "de-reference" a String, for example, as an object name. Bluntly, how do I dynamically name my new objects that I didn't anticipate creating (not in kind but in number)? IOW, how do I take a cleverly constructed string that actually contains code I want run and then ask Java to run it? What's the Java syntax for that? Maybe the problem can be reduced to just object names; Say, the name comes as a string I can construct; how do use that in my JMenuItem declaration? ...I know how to do this in BASH, but how is this done in Java?
(I'm hoping I don't have to create it as a file, compile it, and somehow attach the class file(s) to my running program and then run it - DAMN that would be cumbersome!)
Thanks.
If I understand your overall intent, then I would recommend starting with the Actions API which be used to create independent units of work which are independent of how they are displayed.
This allows you to define re-usable (or in your case, dynamic) operations, which can be executed via menus, toolbars, buttons and even key bindings out of the box.
Because setting up a Action can be a little tedious, I might consider using a builder pattern, but you don't have to, you can build them manually if you wish ;)
public class ActionBuilder {
private ActioBuilderAction action;
public ActionBuilder() {
action = new ActionBuilder.ActioBuilderAction();
}
public ActionBuilder toolTip(String text) {
action.putValue(Action.SHORT_DESCRIPTION, text);
return this;
}
public ActionBuilder command(String text) {
action.putValue(Action.ACTION_COMMAND_KEY, text);
return this;
}
public ActionBuilder mnemonic(int key) {
action.putValue(Action.MNEMONIC_KEY, key);
return this;
}
public ActionBuilder displayedMnemonicIndex(int index) {
action.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, index);
return this;
}
public ActionBuilder text(String text) {
action.putValue(Action.NAME, text);
return this;
}
public ActionBuilder smallIcon(Icon icon) {
action.putValue(Action.SMALL_ICON, icon);
return this;
}
public ActionBuilder largeIcon(Icon icon) {
action.putValue(Action.LARGE_ICON_KEY, icon);
return this;
}
public ActionBuilder acceleratorKey(KeyStroke ks) {
action.putValue(Action.ACCELERATOR_KEY, ks);
return this;
}
public ActionBuilder actionListener(ActionListener listener) {
action.setListener(listener);
}
public Action build() {
return action;
}
public class ActioBuilderAction extends AbstractAction {
private ActionListener listener;
public void setListener(ActionListener listener) {
this.listener = listener;
}
#Override
public void actionPerformed(ActionEvent e) {
if (listener != null) {
listener.actionPerformed(e);
}
}
}
}
Then, you could simply build a new menu something like...
Action action = new ActionBuilder().text("Super awesome command").actionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Super aweseom comand GO!");
}
}).build();
JMenuItem mi = new JMenuItem(action);
Now, I imagine, you might have a "command executor" class of some kind, which would. physically execute the command. I'd create a bridging class which implemented ActionListener and when it's called, would then execute the specified command
public class CommandListener implements ActionListener {
private String command;
public CommandListener(String command) {
this.command = command;
}
#Override
public void actionPerformed(ActionEvent e) {
CommandExecutor executor = new CommandExecutor();
executor.execute(command)
}
}
This could then be used in place of the ActionListener in the first example...
Action action = new ActionBuilder().text(commandName).actionListener(new CommandListener(command)).build();
As an overall idea
I want to find out whether method for some object is being called for that instance or not.
Is it possible in java ?
Like ...
class Button {
public void focus(){}
public void setName(){}
}
class MyTest {
public static void main(String[] args){
Button button = new Button();
button.focus();
// I want to find out on button instance whether focus() or setName() is called or not.
whetherMethodCalled(button);
// OR
whetherMethodCalled(button, 'focus');
whetherMethodCalled(button, 'setName');
}
}
EDIT : Forgot to add Button class is third party class which I cannot modify... Also I want to check in my code whether method has called for given object instance or not on basis of that I have to write some code.
In order to reduce extra work, perhaps profiling your application with JConsole or another tool is good enough to show if certain methods have run. Another option is using a code coverage tool like EMMA which detects dead code. There is a list of open-source profilers for Java at http://java-source.net/open-source/profilers and EMMA is at http://emma.sourceforge.net/.
With some extra work AspectJ could be use to intercept method calls without changing existing code. For example, the following would intercept calls to Button.focus()
#Aspect
public class InterceptButtonMethods {
#Before("execution(* Button.focus())")
public void beforeInvoke() {
System.out.println("Button.focus invoked");
incrementFocusCount();
}
}
If more extra work is ok, there is a way to wrap all calls to the Button's focus() and setName() methods so that they update separate counters in addition to their normal functions. This can be done by extending Button in YourButton class which is identical to Button except for a couple of int counters with getters, setters and increment methods; and countingFocus() and countingSetName() methods which update their counters and call focus() and setName() respectively, such as in outline:
Class YourButton extends Button {
int focusCount;
int setNameCount
int getFocusCount() {return this.focusCount;}
void setFocusCount(int counter) {this.focusCount = counter} // optional to reset counter
void incrementFocusCount() {this.focusCount = getFocusCount() + 1;)
...
void countingFocus() {
incrementFocusCount();
focus()
}
...
}
If it is required in many places and involves complex things, I recommend to use Mockito to test your code. Using that you can verify if the method was invoked (also how many times if invoked)
You can mock the button and verify in your MyTest how many times the method must be called. Using Mockito you can mock and stub your methods(Stubbing voids requires different approach from when(Object) because the compiler does not like void methods inside brackets) and then verify it using verify statement.
verify(mockButton, times(1)).focus();
verify(mockButton, times(1)).setName();
You can write a wrapper class over the 3rd party Button class through which all calls to Button class will be made.
This wrapper class can keep track of whether each method has been called or not
class ButtonCaller {
private Button button = null;
private boolean focusCalled;
private boolean setNameCalled;
public ButtonCaller() {
button = new Button();
focusCalled = false;
setNameCalled = false;
}
public void focus() {
button.focus();
focusCalled = true;
}
public void setName() {
button.setName();
setNameCalled = true;
}
public void whetherMethodCalled(ButtonMethod method) {
switch (method) {
case FOCUS:
return focusCalled;
case SET_NAME:
return setNameCalled;
}
throw new RuntimeException("Unknown ButtonMethod !!!");
}
public static Enum ButtonMethod {
FOCUS,
SET_NAME;
}
}
for example i create this on click
//this creates autor object with default constructor properties defined in autor class
menuAutor.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e)
{
autor Autor = new autor("Autor");
}
});
so object named Autor is created, and when i click again on the button, it pops up again the same Autor object.. how can prevent opening the same window if one is already opened?
EDIT: FINALY A SOLUTION!
After lots of thinking about this.. i made my solution...
default value for autorOpen="no" i declaired at the beginning of my class, just to let you know because its not visible in code below, the solution itself:
public void mouseClicked(MouseEvent e)
{
if(autorOpen=="no") {
autor Autor = new autor("Autor");
autorOpen = "yes";
Autor.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
autorOpen = "no";
}
});
}
else
JOptionPane.showMessageDialog(null, "Demo notice... you can't open that window again.. its opened already!","Error",JOptionPane.ERROR_MESSAGE);
}
});
Store the variable a little bit more globally, and check whether it exists before creating a new one.
You could also consider implementing Autor as a singleton class (to ensure only one is ever instantiated).
public class Autor {
private static Autor instance = null;
//Must be protected or private, get a reference to this class with getInstance().
protected Autor() {
}
/**
* Returns reference to this class - use in place of constructor
*/
public static Autor getInstance() {
if(instance == null) {
instance = new Autor();
}
return instance;
}
}
Use a boolean flag to indicate if the dialog is up or not. Set it to true if the dialog is popped up, and set it to false when you close that dialog.
If you're creating something with 'new' on each click, you'll get a new window each time. One solution is to create autor before any clicks happen, then have the event move it from hidden to visible.
I'm using netbeans to program something with a user interface...
I hava a main class that named "NewJFrame.java"(A) and one more class
that named "NewClass.java"(B). Class A is extended to class B like this:
public class NewClass extends NewJFrame{
...
}
Contents of ClassA are public static like this:
public static javax.swing.JTextField TextBox1;
I also has a button in classA .So when I click the button, it will call a function
from the classB and that function needs to edit TextBox1's text...
Here is whats going on when I click the button:
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String Str1;
NewClass nc = new NewClass();
Str1=nc.call();
}
Here is the funcion in ClassB:
public String call()
{
String Str;
Str = TextBox1.getText();
TextBox1.setText(Str + "1"); //This part isn't work.
JOptionPane.showConfirmDialog(null,Str,"22222222",JOptionPane.PLAIN_MESSAGE);
return Str;
}
So I can read the text of TextBox1 and show it in a messagebox but cannot edit his text.
If I put this code in main class it works perfectly but in another class it doesn't work.
Can someone help me to reslove this problem?
(I'm using netbeans 6.9.1)
I Just Trying to use some another class to add my code because I dont want all the codes stay in same file this is not usefull... Come on someone needs to know how to do that you can't be writing all the codes in a *.java file right?
The problem you are facing has nothing to do with NetBeans IDE,
you will face the same problem with any IDE for this code.
One way of achieving this is by aggregating the NewJFrame class in the NewClass
instead of extending it:
Let me exlplain with some code:
public class NewClass {
private NewJFrame frame = null;
public NewClass(NewJFrame frame) {
this.frame = frame;
}
public String call()
{
String text;
text = frame.TextBox1.getText();
frame.TextBox1.setText(text + "1"); //This will work now.
JOptionPane.showConfirmDialog(null,text,"22222222",JOptionPane.PLAIN_MESSAGE);
return text;
}
}
Here we will receive a reference to the calling JFrame class and will use fields
defined in that class.
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String Str1;
NewClass nc = new NewClass(this); // see the parameter we are passing here
Str1=nc.call();
}
When we create an object of class NewClass we will pass the reference of the
currently calling NewJFrame object
This will work check it.
Now coming to why your code is not working. When NewClass is extending NewJFrame
and when you create a new object of NewClass class it contains a separate
copy of the NewJFrame which is different from the calling NewJFrame reference hence
the field is getting set in another JFrame and not what you wanted.
with regards
Tushar Joshi, Nagpur
AFAIK Netbeans prevents you from editing by hand GUI's and behaves diferrently depending on strange issues like the one you have... but it was months ago, I dont know if current version sucks that much yet.
I really don't understand why you are forcing yourself to use a new class for this? Even if you NEED to, I don't understand why NewClass extends NewJFrame since you are only creating an instance to call a method that has nothing to do with GUI.
I think creating NewClass isn't necessary. Writing all the code in one class isn't bad by itself. This really depends on MANY factors: how much is "all the code"? Does it make sense to separate responsibilities? Etc, etc...
So make the JTextField and JButton NOT static and NOT public, and simply do everything in there:
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String str = TextBox1.getText();
TextBox1.setText(str + "1"); //This part isn't work.
JOptionPane.showConfirmDialog(null,Str,"22222222",JOptionPane.PLAIN_MESSAGE);
}
P.S.: variable names are start in lowercase: String str, not String Str.
I Found a solution. I'm throwing the contents whereever I'll use. Here is an Example:
Main class:
private void formWindowOpened(WindowEvent evt) {
Tab1Codes tc1 = new Tab1Codes();
if(!tc1.LockAll(TabMenu1))
System.exit(1);
tc1.dispose();
}
Another class where I added some of my codes:
public boolean LockAll(javax.swing.JTabbedPane TabMenu){
try
{
TabMenu.setEnabledAt(1, false);
TabMenu.setEnabledAt(2, false);
TabMenu.setEnabledAt(3, false);
TabMenu.setEnabledAt(4, false);
}catch(Exception e)
{
JOptionPane.showConfirmDialog(null, "I can't Lock the tabs!",
"Locking tabs...",
JOptionPane.PLAIN_MESSAGE,
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
So, I can edit the contents in another class but it's little useless to send every content I want to read and edit.
If someone knows any short way please write here.
I have a public class which has the following method and instance variable:
public void setImagePanel(JPanel value) {
imagePanel = value;
if (imagePanel != null) {
//method 1 : works
imagePanel.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent evt) {
System.out.println("Here 1");
}
});
//method 2 : does not work
panelResizeListener = new ResizeListener();
imagePanel.addComponentListener(panelResizeListener);
//method 3 : works
//ResizeListener listener = new ResizeListener();
//imagePanel.addComponentListener(listener);
//method 4 : works
//imagePanel.addComponentListener(new ResizeListener());
//method 5 : does not work -- THIS IS THE DESIRED CODE I WANT TO USE
imagePanel.addComponentListener(panelResizeListener);
}
}
public class ResizeListener extends ComponentAdapter {
#Override
public void componentResized(ComponentEvent evt) {
System.out.println("RESIZE 3");
}
}
private ResizeListener panelResizeListener = new ResizeListener();
private static JPanel imagePanel;
Each of the methods above correspond the to code immediately below until the next //method comment. What i don't understand is why i can't use the class instance variable and add that to the JPanel as a component listener.
What happens in the cases above where i say that the method does not work is that i don't get the "RESIZE 3" log messages. In all cases where i list that it works, then i get the "RESIZE 3" messages.
The outer class is public with no other modification except that it implements an interface that i created (which has no methods or variables in common with the methods and variables listed above).
If anyone can help me i would greatly appreciate it. This problem makes no sense to me, the code should be identical.
Man camickr, you were right. Man this was a weird one to solve. There was something else wrong with my code. The order of the methods calls into my class resulted in me adding the listener then another method would end up removing the listener referenced by that variable so of course i would never get events. Thanks a lot for all the help ppl.
I think your problem is that you're declaring panelResizeListener after you're using it. That normally kills just about anything.