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.
Related
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.
For school, I'm attempting to recreate Microsoft's Notepad program using Java's Swing. I'm working on the saving and opening of .txt files, and I'm trying to figure out a way for the program to detect when a change has been made to the document. If a change has been detected and the user chooses to open or create a new file, I want the program to prompt the user if they would like to save their changes before continuing.
My thought for this was to create a flag, called documentChanged, that would initially be false, and which would be set to true whenever a change was made to the JTextArea. To detect this change, I thought of using a TextListener as follows:
public class JNotepad implements ActionListener
{
boolean documentChanged;
JTextArea notepad;
JNotepad()
{
documentChanged = false;
notepad = new JTextArea();
notepad.addTextListener(new TextListener() {
public void textValueChanged(TextEvent te) {
documentChanged = true;
}
});
}
}
However, I learned that Java classes are unable to implement multiple interfaces at once, and I'm already using ActionListeners to implement the items of my notepad's menu bar.
My question is, is there any way to use both TextListener and ActionListener (or any other listener) simultaneously in the same class? If not, what would be my best plan of action for detecting a change in the document?
It was answer in another post. See Text Changed event in JTextArea? How to?
And also see How to Write a Document Listener (DocumentListener) in Oracle, you will see an applet example.
How does your this even compile
notepad = new JTextArea();
notepad.addTextListener(new TextListener() {
// ....
}
since TextListeners are not defined to work with JTextAreas but rather with TextAreas, a completely different beast.
You should add a DocumentListener to your JTextArea's Document.
notepad.getDocument().addDocumentListener(new DocumentListener() {
void insertUpdate(DocumentEvent e) {
documentChanged = true;
}
void removeUpdate(DocumentEvent e) {
documentChanged = true;
}
void changedUpdate(DocumentEvent e) {
documentChanged = true;
}
});
Regarding
My question is, is there any way to use both TextListeners and ActionListeners (or any other listener) simultaneously in the same class?
Use of a DocumentListener has nothing to do with ActionListeners used elsewhere in your program since their domains are orthogonal to each other, i.e., the one has absolutely nothing to do with the other.
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();
...
});
}
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.
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);