java stop people from closing - java

hi i have a full screen program which i dont want people to close unless they have a password i have this code at the moment
public void windowClosing(WindowEvent arg0)
{
System.out.println("HERE");
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (inputValue != "closeplz")
{
}
}
in the if statement i want it to stop the method so that the program doesent close. any help would be greatly aprecheated thanks ste

You have to call
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
on (or within) the JFrame instance. Then the frame will not close unless you do it manually, though windowClosing() will still be called. Inside it, you can then conditionally call
System.exit(1);
which will end the application. Be sure to do any necessary cleanup first.

Check out Closing an Applicaton for a simple class to help you with this. You would need to provide the custom close action that prompts the user for the password.
Using your simple example the code would be:
Action ca = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
JFrame frame = (JFrame)e.getSource();
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (! inputValue.equals("closeplz"))
{
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
}
};
CloseListener cl = new CloseListener(ca);

Related

How can this java code display an output in BlueJ?

The code below is for a graphical user interface that has a loginframe that will enable the user to input their credentials. However, when I run the code it does not show an output. Can anyone help?
public void addComponentsToContainer() {
container.add(userLabel);
container.add(passwordLabel);
container.add(userTextField);
container.add(passwordField);
container.add(showPassword);
container.add(loginButton);
container.add(resetButton);
}
public void addActionEvent() {
loginButton.addActionListener(this);
resetButton.addActionListener(this);
showPassword.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
//Coding Part of LOGIN button
if (e.getSource() == loginButton) {
String userText;
String pwdText;
userText = userTextField.getText();
pwdText = passwordField.getText();
if (userText.equalsIgnoreCase("admin") && pwdText.equalsIgnoreCase("12345")) {
JOptionPane.showMessageDialog( null, "Login Successful" );
Home obj= new Home();
obj.setVisible(true);
// setVisible(false);
} else {
JOptionPane.showMessageDialog ( null, "Invalid Username or Password");
}
}
//Coding Part of RESET button
if (e.getSource() == resetButton) {
userTextField.setText("");
passwordField.setText("");
}
//Coding Part of showPassword JCheckBox
if (e.getSource() == showPassword) {
if (showPassword.isSelected()) {
passwordField.setEchoChar((char) 0);
} else {
passwordField.setEchoChar('*');
}
}
}
}
You're not really showing enough information in this particular case which is why your are asked in comments to supply a Minimal Reproducible Example. Never the less, I'm going to go with the fact that you are utilizing a JPasswordField component.
To start with, for security reasons the JPasswordField#getText() method has been Deprecated as of Java 2 platform v1.2 and replaced with the JPasswordField#getPassword() method which returns a char[] Array of the password entered. Although you may still be able to compile with the getText() method for this component on the Java platform you're working with, you may be experiencing issues with it when actually running the code.
Try using the JPasswordField#getPassword() method instead and see if that makes a difference:
String userText = userTextField.getText();
String pwdText = String.valueOf(passwordField.getPassword());
if (userText.equalsIgnoreCase("admin") && pwdText.equalsIgnoreCase("12345")) {
and it should fly...maybe...who knows without a Minimal Reproducible Example. Are you using a JPasswordField or are you using a JTextField with a DocumentFilter to mask the entered text?
Maybe your code is working and you just can't see the Message Box because you use null as the parent for the JOptionPane:
JOptionPane.showMessageDialog( null, "Login Successful" );
and the message box dialog window is sitting behind your application window. This is rather typical if the application window has the setAlwaysOnTop() property set to boolean true. This can give the impression that the application is hanging. Give the dialog a parent...perhaps try loginButton instead of null.
On a side note:
Consider hashing passwords then compare a hash with a hash. You really shouldn't hard-code or store a password as plain-text.

How do you make a program wait for user input?

I'd like to use the variable column_input later.
public static void playGame(){
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String input = textField.getText();
chosen_column = Integer.parseInt(input);
textField.setText(null);
}
});
}
Looks like you only need a single piece of data. The easiest solution is to use a JOptionPane. You can prompt for user input.
Read the section from the Swing tutorial on How to Make Dialogs for more information and working examples to get you started.

How to create a graph window in java

I'm using this code
private void botaoGrafADMouseClicked(java.awt.event.MouseEvent evt) {
try {
boolean[] b=new boolean[8];
if (Caixa9.isSelected()) b[0]=true; else b[0]=false;
if (Caixa11.isSelected()) b[1]=true; else b[1]=false;
if (Caixa10.isSelected()) b[2]=true; else b[2]=false;
if (Caixa12.isSelected()) b[3]=true; else b[3]=false;
b[4]=false;b[5]=false;b[6]=false;b[7]=false;
final LineChartDemo1 demo = new LineChartDemo1("Leitura A/D",b,"outad.txt",4);
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Comunicacao.class.getName()).log(Level.SEVERE, null, ex);
}
}
to call an graph interface. But, when I do this, every time I call the graph, it generates on new window and, if I close on of these windows, the whole program is closed.
I'd want to know what am I doing wrong. How Can I avoid this (I would post a printscreen, but, as new user, I can't, it is on http://i.stack.imgur.com/4JLxQ.png I think
Edit: Image
JFrame has a default close operation (i.e. what happens when you close the window using your window manager) of EXIT_ON_CLOSE. Use JFrame.setDefaultCloseOperation to set a different value.
I don't know what the class LineChartDemo1 is, but you could probably set it as the content of a JDialog and call setDefaultCloseOperation (JDialog.DISPOSE_ON_CLOSE) on each dialog. This way, when the user closes the dialog, only that window will close, the others will remain open.
I created a new netbeans JFrame and made reference to it like this:
InterfaceGrafico minhaInterface = new InterfaceGrafico("Leitura I/O",b,"outio.txt",8);
where the arguments where the same to generate the graph. In this "InterfaceGrafico" class:
public InterfaceGrafico(final String title,boolean[] b, String nomeArquivo, int col) {
try {
initComponents();
final LineChartDemo1 demo = new LineChartDemo1("Leitura I/O", b, "outio.txt", 8);
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(InterfaceGrafico.class.getName()).log(Level.SEVERE, null, ex);
}
}
That means, I just shifted the code to another JFrame. I also commented the public void run method . Now I can close each graph generated without closing the whole application and the other generated graphs. In the "LineChart1" class, I added this
public void windowClosing(final WindowEvent evt){
if(evt.getWindow() == this){
dispose();
}
}

Passing input from JButton to console

statsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
//Return the string "stats" to gameLoop() as cmd
}
});
public void gameLoop(){
Scanner lineScanner = new Scanner(System.in);
cmd = "";
System.out.print(getBoard().printBoard(false));
while (!cmd.equals("quit")) {
System.out.print(">");
Scanner wordScanner = new Scanner(lineScanner.nextLine());
if (wordScanner.hasNext()) {
cmd = wordScanner.next();
if (cmd.equals("board")) {
System.out.print(getBoard().printBoard(false));
} else if (cmd.equals("ships")) {
System.out.print(getBoard().printBoard(true));
} else if (cmd.equals("help")) {
printHelp();
} else if (cmd.equals("stats")) {
printStats();
} else if (cmd.equals("fire")) {
if(fire(wordScanner)) {
printStats();
cmd = "quit";
}
} else if (cmd.equals("quit")) {
} else if (!cmd.equals("")) {
System.out.println(ILLEGAL_COMMAND);
}
}
}
}
What I'm trying to do is that when the user clicks the statsButton, the String cmd in the gameLoop would be changed to "stats". The statsButton and the gameLoop() are located in two different classes. Anyone can give me an idea how to do it? (I've attempted pipedreader/pipedwriter) and I just can't seem to get it right.
*I'm basically trying to make my console application into a GUI application without changing the original console application.
Edit: What I've tried
Class textBased
PipedInputStream in = new PipedInputStream()
public void gameLoop(){
try{
in.connect(GUIclass.out);
Scanner lineScanner = new Scanner(in);`
Class GUIclass
PipedOutputStream out = new PipedOutputStream();
PrintWriter writer;
public GUIclass(){
final PrintWriter writer = new PrintWriter(out);
statsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
writer.println("stats");
}
});
that's what I tried writing but it doesn't seem to work.
Regarding
I'm basically trying to make my console application into a GUI application without changing the original console application..."
My advice is simple: "don't do it".
The two applications have completely different structure, one being linear, the other being event-driven, and are not directly translatable to each other. Better to make a new GUI program from the ground up. Now if your non-GUI application contains some well-structured and behaved object-oriented classes, then by all means use those classes in your GUI's "model" or logic section, but don't try to directly translate the program flow of one type of application to the other.
Edit
Based on your posted requirements:
"You should be able to play your Battleship game through your GUI interface. In addition, the text-based front-end you wrote for project 1 should still "work" and be playable."
Correct me if I'm wrong, but I'm betting that you have several classes involved here, and only one of them is the "text-based front-end". If so, then use the non front-end classes as the model of your GUI as I suggested above, but do not use the text-based front-end for anything GUI related, and do not try to emulate it in your GUI.
Have the console application instantiate the button ActionListener and pass it to the UI. When the action event is fired, the listener will tell the console app that it happened. The method in the ActionListener will tell it what to do.
I agree with Hovercrafts comment (changed to a reply).
But in general for problems like this I would change the method signature of your gameLoop(). I would use:
public void gameLoop(Reader reader)
Then you can pass different types of readers to the loop depending on the requirement.
For a console you might do something like:
gameloop( new InputStreamReader( System.in ) );
For a GUI you could do something like:
gameLoop ( new StringReader("some text") );
Edit:
Without changing the method signature you can redirect System.in to come from the String retrieved by the ActionListener:
public class Test
{
public static void main(String args[]) throws Exception
{
String text = "some text";
System.setIn( new ByteArrayInputStream( text.getBytes() ) );
// gameloop();
Scanner lineScanner = new Scanner(System.in);
System.out.println( lineScanner.nextLine() );
}
}
If you have something like this :
class B {
public void gameLoop(){
..
}
}
and
class A{
statsButton.addActionListener(new ActionListener() {
...
});
}
You can declare reference to B in A with final . In that case it's will be visible in inner class ActionListener.
class A{
final B b = ...; //final variable is visible in inner class
statsButton.addActionListener(new ActionListener() {
b.gameLoop();
...
});
}

JTextField key listener is one behind after pasting

I am trying to check that the text in a JTextField matches a perticular pattern, and if it does / doesn't display a message the user. This is what I have so far:
public class input extends KeyListener{
// Some code here
final JTextField inputField = new JTextField(35);
// Some more code...
public void generate(){
// Some GUI code here...
inputField.addKeyListener(this);
}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {
if(e.getSource() instanceof JTextField && e.getSource().equals(inputField)){
if(Pattern.matches("../../....", (JTextComponent) e.getSource()).getText())))
System.out.println("Yh, it works");
else System.out.println("EPIC FAIL (LOL)");
}
}
}
And it does actually work almost perfectly. However, if I paste something using CTRL + V, I have to type two more characters (as opposed to one) before the KeyListener registers that the string is different! So does any one have any idea's why?
Sorry if I have missed out any details - I have tried to make the post as short and concise as possible; so please don't hesitate to ask anything...
For starters, don't use a KeyListener for this type of problem as it is doomed to fail, and even if you get it to work, it's a kludge at best. Instead I'd use either an ActionListener if I wanted to do my checking after the user is completely done entering information, or a DocumentListener if I want to check input as a user is entering, but am not going to block that entering or change the displayed text, or a Document Filter if I'm going to check the input as the user is entering and block it or change it if it is not appropriate.

Categories

Resources