Make JFrame notify main when it closes [duplicate] - java

This question already has answers here:
Swing GUI doesn't wait for user input
(2 answers)
Closed 6 years ago.
So, I started studying java about a week ago, I'm running into a few issues with a little program I'm building to train with swing and oop/java in general.
The program (so far) has a MainClass and a Window class.
The MainClass creates an instance of the Window class, which creates a JFrame and saves the user input in a field .
At this point, MainClass prints the output, which I get through getters methods.
The problem is that I still think in a procedural way: MainClass prints null, because it doesn't wait for the istance of window to get user input.
How can I fix it, thus getting main to wait for the istance of window to accept user input, before printing?
Nb. The Jframe stuff works, the window appears, it's just that MainClass doesn't wait for it to do what it's supposed to. I could (I think?) use some sleep command to wait but it seems utterly wrong.
here's the code of MainClass.java
import java.util.Arrays;
public class MainClass {
private char[] password;
private String pin;
public static void main(String[] args) {
Window w = new Window();
System.out.println(w.getPin() + Arrays.toString(w.getPassword()) + '1');
}
}
and Window.java
import java.awt.*;
import javax.swing.*;
import java.awt.Window.Type;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import net.miginfocom.swing.MigLayout;
public class Window extends JFrame{
private JTextField textField_1;
private JButton btnNewButton;
private JPanel panel;
private JPasswordField passwordField;
private char[] password = new char[10];
private String pin;
public Window() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setSize(370, 150);
this.setForeground(new Color(192, 192, 192));
this.setTitle("Access Password Manager");
this.setResizable(false);
panel = new JPanel();
getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new MigLayout("", "[70.00][132.00,grow][44.00][67.00,grow][61.00][]", "[19.00][34.00][]"));
JLabel lblNewLabel = new JLabel("Password");
panel.add(lblNewLabel, "cell 0 1,alignx trailing,aligny center");
passwordField = new JPasswordField();
passwordField.setColumns(13);
panel.add(passwordField, "cell 1 1,alignx center");
JLabel lblNewLabel_1 = new JLabel("Key");
panel.add(lblNewLabel_1, "cell 2 1,alignx center,aligny center");
textField_1 = new JTextField();
panel.add(textField_1, "cell 3 1,alignx left,aligny center");
textField_1.setColumns(4);
btnNewButton = new JButton("Log In");
ListenForButton listener = new ListenForButton();
btnNewButton.addActionListener(listener);
panel.add(btnNewButton, "cell 4 1");
this.setVisible(true);
}
private class ListenForButton implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnNewButton){
if (passwordField.getPassword().length < 10){
password = passwordField.getPassword().clone();
}
pin = textField_1.getText();
}
}
}
public char[] getPassword(){
return password;
}
public String getPin(){
return pin;
}
}
EDIT:
It's not just about printing, which I know I could do directly into Window.class.
I'm sorry if I explained myself poorly. Please consider the println as a "I need to access and work on those fields once window has saved them form the input".

You could use a modal dialog to get user input, the dialog will block the code execution at the point it is made visible and continue when it's made invisible (it's magic), have a look at How to Make Dialogs for more details
Updated
The modal dialog will only block the Event Dispatching Thread (technically it doesn't block it, it simply circumvents it), see Initial Threads for more details
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import net.miginfocom.swing.MigLayout;
public class MainClass {
private char[] password;
private String pin;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
System.out.println("Before Window");
Window w = new Window();
System.out.println("After Window");
System.out.println(w.getPin() + Arrays.toString(w.getPassword()) + '1');
}
});
}
public static class Window extends JDialog {
private JTextField textField_1;
private JButton btnNewButton;
private JPanel panel;
private JPasswordField passwordField;
private char[] password = new char[10];
private String pin;
public Window() {
this.setModal(true);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setSize(370, 150);
this.setForeground(new Color(192, 192, 192));
this.setTitle("Access Password Manager");
this.setResizable(false);
panel = new JPanel();
getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new MigLayout("", "[70.00][132.00,grow][44.00][67.00,grow][61.00][]", "[19.00][34.00][]"));
JLabel lblNewLabel = new JLabel("Password");
panel.add(lblNewLabel, "cell 0 1,alignx trailing,aligny center");
passwordField = new JPasswordField();
passwordField.setColumns(13);
panel.add(passwordField, "cell 1 1,alignx center");
JLabel lblNewLabel_1 = new JLabel("Key");
panel.add(lblNewLabel_1, "cell 2 1,alignx center,aligny center");
textField_1 = new JTextField();
panel.add(textField_1, "cell 3 1,alignx left,aligny center");
textField_1.setColumns(4);
btnNewButton = new JButton("Log In");
ListenForButton listener = new ListenForButton();
btnNewButton.addActionListener(listener);
panel.add(btnNewButton, "cell 4 1");
this.setVisible(true);
}
private class ListenForButton implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnNewButton) {
if (passwordField.getPassword().length < 10) {
password = passwordField.getPassword().clone();
}
pin = textField_1.getText();
}
}
}
public char[] getPassword() {
return password;
}
public String getPin() {
return pin;
}
}
}

you should be using events. your main class could listen for an event, if the button in the window is pressed. e.g.
public static void main(String[] args) {
Window w = new Window();
w.getBtnNewButton().addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(w.getPin() + Arrays.toString(w.getPassword()) + '1');
}
});
}
in this case you have to make a public getter for the button, so you can access it from the main class.

If you want the result to be printed on button click, then you could print it in the button's action listener. If you want it to be printed as soon as user enters anything, you can add action listeners to your password text field.
Window / View
public class Window extends JFrame{
private Controller controller;
private Model model;
public Window(Controller controller, Model model) {
this.controller = controller;
this.model = model;
}
Model
public class Model {
private String password;
//getters and setters
}
Controller
public class Controller {
public void doSomething() {
// do anything. Views could invoke controller methods to do things and is usually invoked when certain events happen.
}
Main
public class Main {
public static void main(String[] args) {
new Window(new Controller(), new Model());
}

Related

How to make my button do something in a BoxLayout?

I made a BoxLayout GUI and i'm wondering how i'd use an actionlistener to make the button close the window. If I try to put in RegisterNew.setVisible(false); in an actionlistener, it gives me an error
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RegisterNew extends JFrame
{
public RegisterNew(int axis){
// creates the JFrame
super("BoxLayout Demo");
Container con = getContentPane();
con.setLayout(new BoxLayout(con, axis));
con.add(new JLabel("Enter your desired username"));
con.add(new JTextField());
con.add(new JLabel("Enter your password"));
con.add(new JTextField());
con.add(new JButton("Create Account"));
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String args[])
{
RegisterNew newDemo = new RegisterNew(BoxLayout.Y_AXIS);
}
}
I'm also trying to link this to ANOTHER GUI so that when you press a button, this one appears, but it gives me the same error as if i put
RegisterNew.setVisible(true); into the action listener
If that's a subordinate dialog window, then use a JDialog, not a JFrame.
If your ActionListener is an inner class then use RegisterNew.this.close();
Else you can get the window ancestor for the JButton using SwingUtilities.getWindowAncestor(button) and call close() or better dispose() on the Window returned.
Note that BoxLayout and layout managers in general have nothing to do with your current problem.
e.g.,
Test class that shows the new register dialog and that extracts information from it.
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class TestRegistration extends JPanel {
private JTextArea textArea = new JTextArea(30, 60);
public TestRegistration() {
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton(new ShowRegisterNewAction()));
textArea.setFocusable(false);
textArea.setEditable(false);
setLayout(new BorderLayout());
add(new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
add(bottomPanel, BorderLayout.PAGE_END);
}
private class ShowRegisterNewAction extends AbstractAction {
private RegisterNew registerNew = null;
public ShowRegisterNewAction() {
super("Show Register New Dialog");
putValue(MNEMONIC_KEY, KeyEvent.VK_S);
}
#Override
public void actionPerformed(ActionEvent e) {
if (registerNew == null) {
JButton btn = (JButton) e.getSource();
Window window = SwingUtilities.getWindowAncestor(btn);
registerNew = new RegisterNew(window, BoxLayout.PAGE_AXIS);
}
registerNew.setVisible(true);
String userName = registerNew.getUserName();
String password = new String(registerNew.getPassword());
textArea.append("User Name: " + userName + "\n");
textArea.append("Password: " + password + "\n");
textArea.append("\n");
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("TestRegistration");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TestRegistration());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
New Register class that holds the dialog and has code for displaying it and for extracting information from it. Uses BoxLayout.
import java.awt.Container;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class RegisterNew {
private JDialog dialog = null;
private JTextField nameField = new JTextField(10);
private JPasswordField passField = new JPasswordField(10);
public RegisterNew(Window window, int axis) {
dialog = new JDialog(window, "Register New", ModalityType.APPLICATION_MODAL);
Container con = dialog.getContentPane();
con.setLayout(new BoxLayout(con, axis));
con.add(new JLabel("Enter your desired username"));
con.add(nameField);
con.add(new JLabel("Enter your password"));
con.add(passField);
con.add(new JButton(new AcceptAction()));
dialog.pack();
dialog.setLocationRelativeTo(window);
}
public char[] getPassword() {
return passField.getPassword();
}
public String getUserName() {
return nameField.getText();
}
public void setVisible(boolean b) {
dialog.setVisible(b);
}
private class AcceptAction extends AbstractAction {
public AcceptAction() {
super("Accept");
putValue(MNEMONIC_KEY, KeyEvent.VK_A);
}
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
}
}

Java : Wait for user input on swing window [duplicate]

This question already has answers here:
Swing GUI doesn't wait for user input
(2 answers)
Closed 6 years ago.
So, I started studying java about a week ago, I'm running into a few issues with a little program I'm building to train with swing and oop/java in general.
The program (so far) has a MainClass and a Window class.
The MainClass creates an instance of the Window class, which creates a JFrame and saves the user input in a field .
At this point, MainClass prints the output, which I get through getters methods.
The problem is that I still think in a procedural way: MainClass prints null, because it doesn't wait for the istance of window to get user input.
How can I fix it, thus getting main to wait for the istance of window to accept user input, before printing?
Nb. The Jframe stuff works, the window appears, it's just that MainClass doesn't wait for it to do what it's supposed to. I could (I think?) use some sleep command to wait but it seems utterly wrong.
here's the code of MainClass.java
import java.util.Arrays;
public class MainClass {
private char[] password;
private String pin;
public static void main(String[] args) {
Window w = new Window();
System.out.println(w.getPin() + Arrays.toString(w.getPassword()) + '1');
}
}
and Window.java
import java.awt.*;
import javax.swing.*;
import java.awt.Window.Type;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import net.miginfocom.swing.MigLayout;
public class Window extends JFrame{
private JTextField textField_1;
private JButton btnNewButton;
private JPanel panel;
private JPasswordField passwordField;
private char[] password = new char[10];
private String pin;
public Window() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setSize(370, 150);
this.setForeground(new Color(192, 192, 192));
this.setTitle("Access Password Manager");
this.setResizable(false);
panel = new JPanel();
getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new MigLayout("", "[70.00][132.00,grow][44.00][67.00,grow][61.00][]", "[19.00][34.00][]"));
JLabel lblNewLabel = new JLabel("Password");
panel.add(lblNewLabel, "cell 0 1,alignx trailing,aligny center");
passwordField = new JPasswordField();
passwordField.setColumns(13);
panel.add(passwordField, "cell 1 1,alignx center");
JLabel lblNewLabel_1 = new JLabel("Key");
panel.add(lblNewLabel_1, "cell 2 1,alignx center,aligny center");
textField_1 = new JTextField();
panel.add(textField_1, "cell 3 1,alignx left,aligny center");
textField_1.setColumns(4);
btnNewButton = new JButton("Log In");
ListenForButton listener = new ListenForButton();
btnNewButton.addActionListener(listener);
panel.add(btnNewButton, "cell 4 1");
this.setVisible(true);
}
private class ListenForButton implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnNewButton){
if (passwordField.getPassword().length < 10){
password = passwordField.getPassword().clone();
}
pin = textField_1.getText();
}
}
}
public char[] getPassword(){
return password;
}
public String getPin(){
return pin;
}
}
EDIT:
It's not just about printing, which I know I could do directly into Window.class.
I'm sorry if I explained myself poorly. Please consider the println as a "I need to access and work on those fields once window has saved them form the input".
You could use a modal dialog to get user input, the dialog will block the code execution at the point it is made visible and continue when it's made invisible (it's magic), have a look at How to Make Dialogs for more details
Updated
The modal dialog will only block the Event Dispatching Thread (technically it doesn't block it, it simply circumvents it), see Initial Threads for more details
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import net.miginfocom.swing.MigLayout;
public class MainClass {
private char[] password;
private String pin;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
System.out.println("Before Window");
Window w = new Window();
System.out.println("After Window");
System.out.println(w.getPin() + Arrays.toString(w.getPassword()) + '1');
}
});
}
public static class Window extends JDialog {
private JTextField textField_1;
private JButton btnNewButton;
private JPanel panel;
private JPasswordField passwordField;
private char[] password = new char[10];
private String pin;
public Window() {
this.setModal(true);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setSize(370, 150);
this.setForeground(new Color(192, 192, 192));
this.setTitle("Access Password Manager");
this.setResizable(false);
panel = new JPanel();
getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new MigLayout("", "[70.00][132.00,grow][44.00][67.00,grow][61.00][]", "[19.00][34.00][]"));
JLabel lblNewLabel = new JLabel("Password");
panel.add(lblNewLabel, "cell 0 1,alignx trailing,aligny center");
passwordField = new JPasswordField();
passwordField.setColumns(13);
panel.add(passwordField, "cell 1 1,alignx center");
JLabel lblNewLabel_1 = new JLabel("Key");
panel.add(lblNewLabel_1, "cell 2 1,alignx center,aligny center");
textField_1 = new JTextField();
panel.add(textField_1, "cell 3 1,alignx left,aligny center");
textField_1.setColumns(4);
btnNewButton = new JButton("Log In");
ListenForButton listener = new ListenForButton();
btnNewButton.addActionListener(listener);
panel.add(btnNewButton, "cell 4 1");
this.setVisible(true);
}
private class ListenForButton implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnNewButton) {
if (passwordField.getPassword().length < 10) {
password = passwordField.getPassword().clone();
}
pin = textField_1.getText();
}
}
}
public char[] getPassword() {
return password;
}
public String getPin() {
return pin;
}
}
}
you should be using events. your main class could listen for an event, if the button in the window is pressed. e.g.
public static void main(String[] args) {
Window w = new Window();
w.getBtnNewButton().addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(w.getPin() + Arrays.toString(w.getPassword()) + '1');
}
});
}
in this case you have to make a public getter for the button, so you can access it from the main class.
If you want the result to be printed on button click, then you could print it in the button's action listener. If you want it to be printed as soon as user enters anything, you can add action listeners to your password text field.
Window / View
public class Window extends JFrame{
private Controller controller;
private Model model;
public Window(Controller controller, Model model) {
this.controller = controller;
this.model = model;
}
Model
public class Model {
private String password;
//getters and setters
}
Controller
public class Controller {
public void doSomething() {
// do anything. Views could invoke controller methods to do things and is usually invoked when certain events happen.
}
Main
public class Main {
public static void main(String[] args) {
new Window(new Controller(), new Model());
}

Custom JOptionPane / How to wait for a button in a frame to be clicked before returning a value to a method

I am trying to create a method which opens up a JFrame with some text and 4 JButtons. I need it to operate just like the methods in the JOptionPane class so that i can do things like
int i = JOptionPane.showConfirmDialog(...);
I want to be able to call the method and wait for one of the buttons to be clicked before returning a value.
This is what I have tried so far but obviously there are a couple of errors. Anybody know what i need to do to make this work and how to get around the errors. Here is the methood
private static String displaySetStatus(String text){
JButton jbtWin = new JButton("Win");
JButton jbtLose = new JButton("Lose");
JButton jbtCancelBet = new JButton("Cancel Bet");
JButton jbtSkip = new JButton("Skip");
JFrame f = new JFrame("Set Status");
f.add(new JLabel(text));
JPanel jpSouth = new JPanel();
jpSouth.add(jbtWin);
jpSouth.add(jbtLose);
jpSouth.add(jbtCancelBet);
jpSouth.add(jbtSkip);
f.add(jpSouth, "South");
f.setSize(200, 150);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
f.setVisible(true);
String status = "Empty";
ActionListener buttonListener = new SetStatusListener();
jbtWin.addActionListener(buttonListener);
jbtLose.addActionListener(buttonListener);
jbtCancelBet.addActionListener(buttonListener);
jbtSkip.addActionListener(buttonListener);
class SetStatusListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
status = ((JButton)e.getSource()).getText();
}
}
while(status.equals("Empty")){
//do nothing - wait until button is clicked
}
f.setVisible(false);
return status;
}
If you want JOptionPane functionality, which is in fact that of a modal dialog window, why not use a JOptionPane for this? Or if that won't work, use a modal JDialog window and not a JFrame. Your while (true) block is going to totally mess up your program, and modality is what you in fact want.
For example:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class Foo1 extends JPanel {
private JTextField textField = new JTextField(10);
private JButton getStatusBtn = new JButton(new GetStatusAction("Get Status"));
public Foo1() {
textField.setFocusable(false);
add(new JLabel("Status:"));
add(textField);
add(getStatusBtn);
}
private class GetStatusAction extends AbstractAction {
public GetStatusAction(String name) {
super(name);
int mnemonic = name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component parentComponent = Foo1.this;
// this panel can hold any gui components that you desire
// here I simply give it a centered JLabel that displays some text
JPanel message = new JPanel(new GridBagLayout());
message.setPreferredSize(new Dimension(200, 100));
message.add(new JLabel("Some Text"));
String title = "Get Status";
int optionType = JOptionPane.OK_CANCEL_OPTION;
int messageType = JOptionPane.PLAIN_MESSAGE;
Icon icon = null;
String[] options = { "Win", "Lose" };
int initialValue = 0;
// create and show our JOptionPane, and get the information from it
int selection = JOptionPane.showOptionDialog(parentComponent,
message, title, optionType, messageType, icon, options,
initialValue);
// if the selection chosen was valid (win or lose pushed)
if (selection >= 0) {
// get the selection and use it
textField.setText(options[selection]);
}
}
}
private static void createAndShowGui() {
Foo1 mainPanel = new Foo1();
JFrame frame = new JFrame("Foo1");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Turning some of the JTextBox to be JLabels in a Sudoku Game

So here is what i have so far for my sudoku game. Now my grid only displays textboxes where a user can input numbers but nothing will happen yet. I want to know how to make it so that the user can only input one character and only numbers. i would also like to know how to make some textboxes jdialogs displaying uneditable numbers that im taking from http://www.websudoku.com/ for the puzzle. Any help would be appreciated. Thanks.
Main Class
import javax.swing.JOptionPane;
public class Game{
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Hello. Welcome to a game of Sudoku by #### ####.");
Level select = new Level();
}
}
Difficulty Select Class
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Level extends JFrame {
private JLabel tag1;
private JButton butt1;
private JButton butt2;
private JButton butt3;
private JButton butt4;
public Level(){
super("Difficulty");
setLayout(new FlowLayout());
setSize(250,130);
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tag1 = new JLabel("Please Select Your Difficulty.");
add(tag1);
butt1 = new JButton("Easy.");
butt1.setToolTipText("For players new to Sudoku.");
add(butt1);
butt2 = new JButton("Medium.");
butt2.setToolTipText("Your abilites will be tested.");
add(butt2);
butt3 = new JButton("Hard.");
butt3.setToolTipText("Your skills will be strained.");
add(butt3);
butt4 = new JButton("Evil!");
butt4.setToolTipText("You will not survive.");
add(butt4);
thehandler handler = new thehandler();
butt1.addActionListener(handler);
butt2.addActionListener(handler);
butt3.addActionListener(handler);
butt4.addActionListener(handler);
}
private class thehandler implements ActionListener{
public void actionPerformed(ActionEvent event){
String string = "";
if(event.getSource()==butt1){
dispose();
string = "Have fun!";
SudokuPanel Squares = new SudokuPanel();
}
else if(event.getSource()==butt2){
dispose();
string = "Good luck!";
SudokuPanel Squares = new SudokuPanel();
}
else if(event.getSource()==butt3){
dispose();
string = "Try to keep your head from exploding...";
SudokuPanel Squares = new SudokuPanel();
}
else if(event.getSource()==butt4){
dispose();
string = "Please refrain from smashing any keyboards.";
SudokuPanel Squares = new SudokuPanel();
}
JOptionPane.showMessageDialog(null, string);
}
}
}
Sudoku Panel Class
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class SudokuPanel extends JFrame {
public final int SQUARE_COUNT = 9;
public Squares [] squares = new Squares[SQUARE_COUNT];
public SudokuPanel(){
super("Sudoku");
setSize(600,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(3,3));
for(int i=0; i<SQUARE_COUNT; i++){
squares[i] = new Squares();
panel.add(squares[i]);
}
JPanel panel2 = new JPanel();
JButton startTime = new JButton();
JButton stop = new JButton();
JButton resetTimer = new JButton();
MyTimer timer = new MyTimer();
startTime = new JButton("Start Timer");
stop = new JButton("Stop Timer");
final JLabel timerLabel = new JLabel(" ...Waiting... ");
resetTimer = new JButton("Reset");
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
JMenuItem newDifficulty = new JMenuItem("Select New Difficulty");
menu.add(newDifficulty);
JMenuItem reset = new JMenuItem("Reset Puzzle");
menu.add(reset);
JMenuItem exit = new JMenuItem("Exit");
menu.add(exit);
exitaction e = new exitaction();
newDifficultyaction d = new newDifficultyaction();
resetaction f = new resetaction();
reset.addActionListener(f);
exit.addActionListener(e);
newDifficulty.addActionListener(d);
panel2.add(timer);
add(panel, BorderLayout.CENTER);
add(panel2, BorderLayout.PAGE_END);
setVisible(true);
setLocationRelativeTo(null);
}
public class exitaction implements ActionListener{
public void actionPerformed (ActionEvent e){
System.exit(0);
}
}
public class newDifficultyaction implements ActionListener{
public void actionPerformed (ActionEvent e){
dispose();
Level select = new Level();
}
}
public class resetaction implements ActionListener{
public void actionPerformed (ActionEvent e){
dispose();
SudokuPanel Squares = new SudokuPanel();
}
}
}
Squares/Cells class
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class Squares extends JPanel {
public final int CELL_COUNT = 9;
public Cell [] cells = new Cell[CELL_COUNT];
public Squares(){
this.setLayout(new GridLayout(3,3));
this.setBorder(new LineBorder(Color.BLACK,2));
for(int i =0; i<CELL_COUNT; i++){
cells[i] = new Cell();
this.add(cells[i]);
}
}
public class Cell extends JTextField{
private int number;
public Cell(){
}
public void setNumber(int number){
this.number = number;
this.setText("1");
}
public int getNumber(){
return number;
}
}
}
Timer Class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyTimer extends Panel {
private JLabel timeDisplay;
private JButton resetButton;
private JButton startButton;
private JButton stopButton;
Timer timer;
public MyTimer(){
startButton = new JButton("Start Timer");
stopButton = new JButton("Stop Timer");
timeDisplay = new JLabel("...Waiting...");
this.add(startButton);
this.add(stopButton);
this.add(timeDisplay);
event e = new event();
startButton.addActionListener(e);
event1 c = new event1();
stopButton.addActionListener(c);
}
public class event implements ActionListener{
public void actionPerformed(ActionEvent e){
int count = 0;
timeDisplay.setText("Elapsed Time in Seconds: " + count);
TimeClass tc = new TimeClass(count);
timer = new Timer(1000, tc);
timer.start();
}
}
public class TimeClass implements ActionListener{
int counter;
public TimeClass(int counter){
this.counter = counter;
}
public void actionPerformed(ActionEvent e){
counter++;
timeDisplay.setText("Elapsed Time in Seconds: " + counter);
}
}
class event1 implements ActionListener{
public void actionPerformed (ActionEvent c){
timer.stop();
}
}
}
I want to know how to make it so that the user can only input one character and only numbers.
There are several ways, all easily discoverable by searching this site, as this problem is a common one. Two I'll mention: use a JFormattedTextField, or use a JTextField whose Document has a DocumentFilter added to it that prevents wrong input from being entered.
i would also like to know how to make some textboxes jdialogs displaying uneditable numbers that im taking from http://www.websudoku.com/ for the puzzle. Any help would be appreciated.
Several possible solutions to this one including
Set the component's enabled property to false.
Set the component's focusable property to false.
Some issues with your post:
You mention use of "textboxes". I recommend you avoid using non-Java non-Swing terms like "textboxes" as they only will serve to confuse. If you are using a specific type of text component and are asking about it, mention the component type by name as solutions may differ depending on the type.
You have posted a wall of code, most of it unrelated to your problem at hand. Please remember that we are volunteers, and please be kind to us. One way is to avoid posting too much unrelated code. Best would be to post a small minimal example program for questions that need this.

Which timer to use for GUI in Java

I have been trying to find the best timer to use for the following code (note this is a simplified version of my overall program). My hope is to run a method after 3 seconds.
The problem is with the actionPerformed, checkBlankLogin, and resetLoginBlank and putting a timer to delay resetLoginBlank from happening 3 seconds after checkBlankLogin has happened. But I want all methods in the class Outerframe to continuously run. So checkBlankLogin will keep checking if its blank until the person inputs the information for a "Valid Input" and the Login innerframe will close. But I don't know how to do that... Any help there also?
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;
import java.io.*;
import java.io.File;
import java.util.*;
import java.io.FileNotFoundException;
class OuterFrame extends JFrame implements ActionListener
{
Container pane; // container
JDesktopPane outframe; // outer frame
JInternalFrame login; // login frame
//pieces of login frame
JLabel loginLBLtitle;
JPanel loginPanel;
JLabel loginLBLname;
JLabel loginBlankName;
JLabel loginLBLpass;
JLabel loginBlankPass;
JTextField loginTXT;
JPasswordField loginPASS;
JButton loginBUT;
JInternalFrame apple;
OuterFrame()
{
//set up for Outer Frame
super("Application");
setSize(450,240);
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
outframe = new JDesktopPane();
outframe.setBackground(Color.BLUE);
//set up for Container
pane = getContentPane();
setContentPane(pane);
pane.add(outframe);
//Login Inner Frame
login = new JInternalFrame();
login.setSize(400,200);
login.setLocation(20,20);
login.setTitle("Member Login");
loginLBLtitle = new JLabel("Sign in with netid and your password.");
Font loginFontbody = new Font("SansSerif", Font.PLAIN, 12);
Font loginFonthead = new Font("SansSerif", Font.BOLD, 13);
loginLBLtitle.setFont(loginFonthead);
loginLBLname=new JLabel("User Name:");
loginLBLname.setFont(loginFontbody);
loginLBLpass=new JLabel("Password: ");
loginLBLpass.setFont(loginFontbody);
loginBUT=new JButton("Login");
loginBUT.setFont(loginFontbody);
loginBUT.addActionListener(this);
loginTXT=new JTextField(20);
loginPASS=new JPasswordField(20);
loginBlankName=new JLabel("");
loginBlankPass=new JLabel("");
loginPanel=new JPanel();
loginPanel.add(loginLBLtitle);
loginPanel.add(loginLBLname);
loginPanel.add(loginTXT);
loginPanel.add(loginBlankName);
loginPanel.add(loginLBLpass);
loginPanel.add(loginPASS);
loginPanel.add(loginBlankPass);
loginPanel.add(loginBUT);
//panel.add(lblmess);
login.add(loginPanel);
login.setVisible(true);
//Add Login to Outer Frame
outframe.add(login);
outframe.setSelectedFrame(login);
pane.add(outframe, BorderLayout.CENTER);
setVisible(true);
loginTXT.requestFocus();
}
public void actionPerformed(ActionEvent e)
{
//problem area
if(e.getSource()==loginBUT)
{
String uname=loginTXT.getText();
String passw=new String(loginPASS.getPassword());
int i=0;
while(i!=5)
{
if(checkBlankLogin(uname,passw,loginBlankName,loginBlankPass))
{
resetLoginBlank(loginBlankName,loginBlankPass);
}
else
{
if(!validateUser("accounts.txt",uname,passw,loginLBLtitle))
{
}
}
}
}
public void resetLoginBlank(JLabel loginBlankName, JLabel loginBlankPass)
{
loginBlankName.setText("");
loginBlankPass.setText("");
}
public void resetLoginTitle(JLabel loginBlankTitle)
{
loginBlankTitle.setText("Sign in with netid and your password.");
loginBlankTitle.setForeground(Color.BLACK);
}
public boolean checkBlankLogin(String name, String passw, JLabel loginBlankName, JLabel loginBlankPass)
{
boolean isBlank=false;
if(name.length()<1)
{
loginBlankMess("User name is required.",loginBlankName);
isBlank=true;
}
if(passw.length()<1)
{
loginBlankMess("Password is required.",loginBlankPass);
isBlank=true;
}
return isBlank;
}
public void loginBlankMess(String mess, JLabel lbl)
{
lbl.setText(mess);
lbl.setForeground(Color.RED);
}
public boolean validateUser(String filename, String name, String password, JLabel title)
{
boolean valid = false;
try
{
File file = new File(filename);
Scanner scanner = new Scanner(file);
ArrayList<String> fileInfo = new ArrayList<String>();
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
fileInfo.add(line);
}
String fullLogin = name + " " + password;
if(fileInfo.contains(fullLogin))
{
//loginBlankMess("Valid login",namemess);
valid=true;
}
if(!valid)
{
loginBlankMess("Please enter valid netid and password.", title);
resetLoginTitle(title);
}
}
catch(Exception ie)
{
System.exit(1);
}
return valid;
}
}
public class TheProgram
{
public static void main(String[] args)
{
new OuterFrame();
}
}`
I would check out the following resource (assuming you using Swing for your UI):
How to Use Swing Timers (Oracle)
Swing timers are the easiest in your case. You make your class implement ActionListener, and create a timer object. The timer will call the actionPerformed method when it expires.
import javax.swing.Timer;
class OuterFrame extends JFrame implements ActionListener{
Timer timer = null;
public void actionPerformed(ActionEvent e) {
if(e.getSource()==loginBUT){
//If the action came from the login button
if (checkBlankLogin()){
timer = new Timer(3000, this);
timer.setRepeats(false);
timer.setInitialDelay(3000);
timer.start();
} else if (timer != null){
timer.stop();
}
}else if(e.getSource()==timer){
//If the action came from the timer
resetLoginBlank(namemess,passwmess));
}
}
}

Categories