My professor assigned a project where a simulation is ran through a GUI. To edit it, we need to create a "New" menu item. We haven't learned how to get data from a GUI, and our book does not cover it at all.
What I'm trying to do, is when the "New" command is hit, focus gets shifted back to the CMD prompt, where System.out. starts working again and prompts the user for input.
However, when I try to implement this, my program crashes. What can I do to solve this problem?
It doesn't look like you're keeping the reference to your newly created GUI. As far as I remember, Java will garbage collect the FoxGui object (as well as any other object) if there are no references to that object. Try creating a global variable to store the reference to your newly created FoxGui object. Something like...
FoxGui MyGUIRef;
public void actionPerformed(ActionEvent event)
{
System.out.println("Item: " + event.getActionCommand());
// File Menu Controls
if (event.getActionCommand().equals("New"))
{
MyGUIRef = runNew();
}
}
//Now returns a reference to FoxGui
private FoxGui runNew()
{
return new FoxGui(....)
}
Is the System.out in a terminal (non Java) window? If so, I think this would be much harder than you'd think.
I'd be tempted to redirect the System.in / System.out to a JTextPane on the GUI (That way, it would be much easier to change the focus etc. I think you need to try and explain what you're doing a little better in your question and perhaps post a stack trace when your program crashes.
Anyway, to do something when the "new" menu item is clicked you'd need to do:
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Code here to be performed when the item is clicked
}
});
You know what? I found a real simple solution, JOptionPane. I just needed to find a good example. It'll work fine for what I want. Thanks for all the help. I'll checkmark everyone who helped.
I know that it is very late answer, but anywhere...
There is only one way to do exactly what you want.
First you need to remember to run you project from CMD by java -jar jarname.jar
Catch click action and perform system.in
Information:
It is the only solution, because GUI never give focus to CMD, but if GUI runned from CMD you can use easily System.in.
Regards, Greg
Related
I have a Java program that's using ProcessBuilder to set up some Servers.
I have also made a Form, that displays a JProgressBar, a JLabel and a JTextArea. The Progressbar is set to be indeterminate, since there doesn't seem to be a way for easy calculation of the workload.
The Label is regularly updated to show the User at which step the programm currently is, and the TextArea displays extra information about the current step.
However, when I start the setup, the Window opens and displays nothing. Just a blank white window with a title.
That is until the setup is either done, or when I'm debugging, where it will sometimes actually display something for a short time.
I have tried calling panel.revalidate() together with panel.repaint() everytime I update a property, but this hasn't changed anything. I remember faintly that there's a specific way to update components while the program is doing stuff in the background, but cannot remember how, and wasn't able to find anything helpful so far.
public void shutdownSystems() throws IOException, InterruptedException {
for (String ip : ipArray) {
if (isWindows) builder.command(ipmitool, ip, "ADMIN", "ADMIN", "ipmi", "power", "down");
loadingForm.setProgressInfo("Shutting down System " + ip);
startProcess();
loadingForm.setProgressInfo(streamGobbler.getResult());
refreshLoadingWindow();
}
}
Here's a piece of code to showcase how I'm trying to do it currently. loadingForm refers to the window which is supposed to have it's components updated. startProcess(); is a local method that executes the command set by the ProcessBuilder builder and compiles the output to also add this information to the window. Last but not least, I call refreshLoadingWindow(); which basically just gets the panel of loadingForm and executes .revalidate(); and .repaint();
The main thing that is confusing me is, while I understand that there's probably a different approach to updating GUIs, it doesn't even show the components at all. Not even when first opening the window.
Can anyone tell me what I'm supposed to be doing instead?
I'm trying to code a program in Java that automatically types each character in a string using the Robot class. I've used it to make a similar automated program a while ago (which I'll refer to as the 'previous project') that used 'keyPress()'. This and most, if not all, of the other methods for the Robot class which I needed to use worked perfectly.
Now I've started and 'keyPress()' isn't typing anything, regardless of the KeyEvent I pass as an argument. I thought I had written the code incorrectly, so I ran my previous project just to make sure it worked, but it didn't.
Here's the snippet of code I used for the previous project and my current one (which you can also use to test this).
EDIT: Try the on a text editor or anything that functions like a text field. I've now shown the entire demo class.
// demo procedure
public class DemoClass() {
public static void main(String[] args) {
new DemoClass().run()
}
public void run() {
try {
Robot robot = new Robot();
for (int i = 1; i <= 30; i++) {
robot.keyPress(KeyEvent.VK_A);
robot.delay(100);
System.out.println("Typed key");
}
} catch (AWTException e) {
e.printStackTrace();
}
}
}
'Typed key' gets printed 30 times and no errors appear in the output either.
I've tried;
adding 'robot.keyRelease(KeyEvent.VK_A)' just after the key press,
allowing the program type in the software I want to automate,
allowing the program to type in the IDE I'm using and in a text editor,
allowing the program to click in the IDE and text editor (so I could see if only pressing keys was the issue).
None of these have produced results. I've checked the code from multiple sources (articles and videos), all of which have the same code stub. I've read that some software prevent Robot objects from typing/clicking in them, but both typing and clicking worked when I was developing my previous project.
So I woke up today and... the program works.
I still don't know why it wasn't working in the first place or how the problem fixed itself (magic?). Running the sudo command didn't seem to make a difference, and none of the software I'm dealing with prevent a Robot object from automated typing/clicking.
It's most likely just a me-problem since other people managed to get it working. Since it's happened once it'll probably happen again.
Anyways, thanks to everyone that helped! If future readers have any ideas of why it didn't work then feel free to share them.
I have a program that I am terminating with the System.exit(0); command.
When this happens the JPanel closes. I would like it to rename open so I can view the state at termination. Is there a way of keeping the Jpanel open or is there a better command than System.exit()?
not sure why a down vote I asked a simple question and someone answered it. I can't do it that way so try something else. Going to use a true false to test where to enter the simulation loop.
regarding:
Is there a way of keeping the Jpanel open or is there a better command than System.exit()?
The best solution: Don't call System.exit(...). Why? Because System.exit(0) closes the JVM, and so all Java processes running on that JVM will shut down when System.exit(0) is called.
As for "better command", that all depends on your need. If you just want to close a window such as a JDialog, then call myWindow.setVisible(false);. If you want to close it and release resources, then myWindow.dispose();.
Note: I suspect that you might have multiple windows open, perhaps multiple JFrames. If so, I strongly urge you to read: The Use of Multiple JFrames, Good/Bad Practice?
You also posted in comments:
I would like to keep the Jpanel open, but stop the simulation from running. I need to stop the Sim when certain conditions are met. so I wrote a stop()
So your question is in fact an XY Problem where you ask how to solve a specific code problem (keep a JPanel open after calling System.exit(0)) when the best solution is to use a completely different approach. Better that you tell us the overall problem that you're trying to solve rather than how you're currently trying to solve it, because System.exit isn't going to be part of the best solution.
Likely the best solution is to well separate your simulation model from its view (the GUI), to be able to give the model functionality that allows it to stop without closing down the JVM -- impossible for me to say how given our current level of knowledge about your problem -- and then reflect the stopping of the model in the view, again without shutting down the system.
The key to all of this will lie in the details of your current program, including the logic that underpins your simulation, and if you need more specific and likely more helpful answers, you're again going to want to improve your question, providing us with much more specific information about your code, your problem and with posting of pertinent code, preferably as a minimal example program.
Have you tried an approach similar to:
Do something when the close button is clicked on a JFrame
Basically, you're grabbing the Window closing event by setting a listener on the frame
You can then .dispose() the appropriate jpanel/frame if you want
JFrame is window and JPanel is a container. The moment the JPanel instance loses its reference, it will be garbage collected
How can JPanel be disposed after the panel has been removed from the JFrame
Disposing JFrame by clicking from an inner JPanel
import javax.swing.JOptionPane;
/*Some piece of code*/
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
//delete this code if you want and replace with .dispose() or anything
if (JOptionPane.showConfirmDialog(frame,
"Are you sure to close this window?", "Really Closing?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION){
//choose to close JVM here if you want
System.exit(0);
}
}
});
Here's a way, by overriding the SecurityManager for the JVM:
//set your security manager
static{
SecurityManager s = new DontCloseOnExitSecurityManager();
System.setSecurityManager(s);
}
static class DontCloseOnExitSecurityManager extends SecurityManager{
public void checkExit(int code){
//here you can put a check to see if you really do want to close - like if the JFrame is still open.
if(/*do some check*/ 13 == code)
super.checkExit(code);
throw new SecurityException("13 is unlucky, you shouldn't system exit on it.");
}
}
}
You'll need to find an appropriate place to put it in, and also how to do your checks (in checkExit).
Apologies for inaccuracies, I'm not in front of an IDE to test this right now.
I'm working on something in NetBeans, and I want to create an actionListener in a jTextPane for when the user presses Enter. However, I also need to input a String array (from a different subroutine within the source code) into the listener. But in NetBeans, events are generated automatically and I'm not allowed to edit this apparently extremely sensitive code. So, then, I tried typing up my own event thing (sorry about my terminology; I'm very new to GUI programming):
private void jTextPaneEnterPressed(KeyEvent evt, String[] stringArray)
{
int key = evt.getKeyCode();
if (key == KeyEvent.VK_ENTER)
{
// do something when the user presses enter that involves the program knowing what stringArray is
}
}
But when I run the program, pressing Enter in the text pane does nothing. I understand that this is because there is no actionListener associated with jTextPaneEnterPressed, but NetBeans gives no option for such customized code.
So what I want to know is either how I can pass in my own parameters when NetBeans creates an event handler, or how I can write my own actionListener alongside this actionPerformed block.
(And for the record, this is not an import problem)
I have tried looking this up, but have found nothing specific, as all other similar issues are not relevant to NB. Any help would be greatly appreciated.
*EDIT: This may seem like a trivial problem to most, but I'm open to any actual answers that tell me how to get done what I am trying to do, though I would prefer to stick with NetBeans. All I need is for the action listener to know that this string array exists, because the program needs to deal with that array when the user presses Enter. I'm sorry I can't give any specific context, but it's too much to get into.
So, I have been working on a reset button and I need help because currently the program just creates an extra copy of itself when I need it to replace the old one instead of adding to it. (This is a java quiz game, btw)
Here is a link to the all of the code https://gist.github.com/anonymous/522b2a89ba2fc6750d2e
here is the code that I specifically need help with:
if(src.equals(restart)){
quiz.showRestartSummary();
//quiz.restart(); not important right now
JavaQuiz quiz2=new JavaQuiz();
The reason for your issue is that you're creating new instances of your Quiz without disposing of the current Quiz in execution.
I Added the line below to your restart() method in your JavaQuiz class, it will close the previous jframe created:
this.dispose();
Also
You can dispatch a windowClosing Event to the jframe, like below:
this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
Make the change below:
public void restart(){
//wrongs=0;
//total=0;
// Change should be made here.
this.dispose();
}