This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
Why this code do not stop when the while loop is empty. If I add an instruction the code work fine. Normally after the the user clicked an button the test variable will be changed so the loop will ends. Is there another way to test that the JDialog was disposed.
public class FenetreAjoutClass extends JDialog {
private JPanel pan = new JPanel();
private JPanel buttPan = new JPanel();
private JTextField schoolLevl = new JTextField();
private JButton valide = new JButton("OK");
private static String infos = null;
private static boolean test = false;
private JButton cancel = new JButton("CANCEL");
FenetreAjoutClass(JFrame parent, Boolean modal) {
valide.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
infos = schoolLevl.getText();
test = true;
dispose();
}
});
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
test = true;
dispose();
}
});
this.setLocationRelativeTo(null);
this.setResizable(true);
this.setLayout(new BorderLayout());
pan.setLayout(new GridLayout(1, 1));
pan.add(schoolLevl);
this.add(pan, BorderLayout.NORTH);
buttPan.add(valide);
buttPan.add(cancel);
this.add(buttPan, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public static void main(String[] args) {
System.out.println(get());
}
public static String get() {
new FenetreAjoutClass(null, false);
while (!test) {
//System.out.println(test);
}
return infos;
}
}
The dispose will free up your memory. All data for the dialog are gone. If you want to show the window later again you have to work with visibility. This can be checked with isVisible().
You can replace the dispose() in your code with this.setVisible(false)
public static String get() {
FenetreAjoutClass dialog = new FenetreAjoutClass(null, false);
while (dialog.isVisible()) {
System.out.println("is Visible");
}
System.out.println("is not Visible");
return infos;
}
Mind that the console will still print "is Visible" over a short time after the dialog is closed. But this is because the console can does not print as quick as the while loop restarts.
Related
This is part of a project for school, and I'm stuck and need someone to bounce ideas off of. I have a game where there is an option to sign up or sign in for a machine-local game so a record can be kept of the person's scores. The game is run from a base GUI JFrame, and I want to make buttons to bring up secondary windows for the person to sign in or sign up, before closing out of them. I need to pass the validated username back to the initial GUI/game class so I can store it for the following game so the game score can be added under that user. I just need to pass the username back and I'm not sure how to go about it. This is the main GUI code up to where I'm having my issue:
public class MathFactsGUI extends JFrame
{
// instance variables
private JTextField problemJTextField, answerJTextField;
private JLabel equalJLabel;
private JButton additionJButton, multiplicationJButton;
private JButton signupJButton, signinJButton;
private JButton submitJButton;
private JLabel scoreJLabel,resultJLabel;
//private JButton reviewButton;
private String username;
private Userbase userbase;
private JLabel introJLabel;
Quiz quiz;
/**
* Constructor for objects of class MathFactsGUI
*/
public MathFactsGUI()
{
super("Math Facts Quiz");
userbase = Userbase.getUserbase();
username = "guest";
/* code here has been removed to be abbreviated */
// Action listener for buttons
additionJButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
quiz = new Quiz('+');
problemJTextField.setText(quiz.getCurrentProblem());
additionJButton.setEnabled(false);
multiplicationJButton.setEnabled(false);
signupJButton.setEnabled(false);
signinJButton.setEnabled(false);
}
});
multiplicationJButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
quiz = new Quiz('x');
problemJTextField.setText(quiz.getCurrentProblem());
additionJButton.setEnabled(false);
multiplicationJButton.setEnabled(false);
signupJButton.setEnabled(false);
signinJButton.setEnabled(false);
}
});
signinJButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JDialo
}
});
signupJButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
MathFactsSignUpGUI signUpGUI = new MathFactsSignUpGUI();
gui.setVisible(true);
}
});
}
This is the JFrame I wrote for the sign-up button:
public class MathFactsSignUpGUI extends JDialog {
private JTextField usernameJTextField, userPassJTextField, userFirstNameJTextField;
private JLabel usernameJLabel, userPassJLabel, userFirstNameJLabel;
private JButton submitJButton;
private String username;
private String userPass;
private String userFirstName;
public MathFactsSignUpGUI(){
usernameJLabel = new JLabel("Username:");
usernameJTextField = new JTextField();
userPassJLabel = new JLabel("Password:");
userPassJTextField = new JTextField();
userFirstNameJLabel = new JLabel("Player First Name:");
userFirstNameJTextField = new JTextField();
Box usernameBox = Box.createHorizontalBox();
usernameBox.add(usernameJLabel);
usernameBox.add(usernameJTextField);
Box userPassBox = Box.createHorizontalBox();
userPassBox.add(userPassJLabel);
userPassBox.add(userPassJTextField);
Box userFirstBox = Box.createHorizontalBox();
userFirstBox.add(userFirstNameJLabel);
userFirstBox.add(userFirstNameJTextField);
submitJButton = new JButton("Submit");
submitJButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
username = usernameJTextField.getText();
userPass = userPassJTextField.getText();
userFirstName = userFirstNameJTextField.getText();
if (!checkValid(username) || !checkValid(userPass) || !checkValid(userFirstName)){
JOptionPane.showMessageDialog(null, "All fields must have values.");
} else if (Userbase.getUserbase().userExist(username)==true){
JOptionPane.showMessageDialog(null, "Username is taken, please choose another.");
} else {
Userbase.getUserbase().addUser(username, new User(username, userPass, userFirstName));
MathFactsGUI.setUsername(username);
}
}
});
JPanel mfSignUp = new JPanel()
mfSignUp.setLayout(new GridLayout(0,1));
mfSignUp.add(usernameBox);
mfSignUp.add(userPassBox);
mfSignUp.add(userFirstBox);
mfSignUp.add(submitJButton);
}
public String signIn(){
return username;
}
public boolean checkValid(String a){
if (a == null || a.length() == 0){
return false;
} else {
return true;
}
}
}```
I was thinking of implementing a WindowListener action for when the sign-up/sign-in frames close, but I'm not sure that will work. I was also looking into JDialog, but I'm not sure if it has the layout/text verification properties I need.
Use a JOptionPane. It will simplify your layout without the need for creating a separate JFrame and easily pass values back to wherever it was called from. You can then make it check for valid username when you click OK.
Try this site. It gives a good rundown with example images
First you need to understand that this is an object, so you can create some global variables which will contains this information(username,password,Nickname), i recommend to pull info from MathFactsSignUpGUI by using ScheduledExecutorService. It will pull info from this sign up gui in every 100ms, than it will destroy itself, here is an example:
MathFactsSignUpGUI su = new MathFactsSignUpGUI ();
su.setVisible(true);
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.schedule(new Runnable(){
public void run(){
if(!su.username.isEmpty() && !su.userPass.isEmpty() && !su.userFirstName.isEmpty() ){
if(su.isLogin){ //if player is loggining
//do something here
}else{//if user is registered
//do something here
}
System.out.println("Check complete");
service.shutdown();//to destroy this service after recieving the data
}
}
}, 100, TimeUnit.MICROSECONDS);
I'm trying to put a conditional in a JDialog which detect if the two buttons in it are disabled. I need that also to close the dialog when it reach this condition so I found 2 problems. Example code:
public static String windowvisitAlert(JButton but, JButton but2, String message1, String message2) throws Exception, Exception {
String n = "";
Object[] options = {but, but2};
Object a = message1;
JOptionPane pane = new JOptionPane(a, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, options[0]);
JDialog dialog = pane.createDialog(message2);
dialog.setContentPane(pane);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(new Dimension(450, 10));
dialog.pack();
dialog.setVisible(true);
return n;
}
This is the method which creates a JDialog from a JPanel options. We have 2 buttons and 2 "messages" which only determinates the name of the dialog window.
I tried to put :
if (but.isEnabled()==false && but2.isEnabled()==false) {
dialog.setVisible(false);
}else{
dialog.setVisible(true);}
Also this method will return the value n so I don't know how will a condition work inside it.
Where i implement this method:
public void actionPerformed(ActionEvent e) {
final JButton but = new JButton("VISITA");
final JButton but2 = new JButton("RESPONSABLE");
try {
ActionListener actionListener2 = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
//action performed
}
};
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
//action performed
}
};
but.addActionListener(actionListener2);
but2.addActionListener(actionListener);
Alerts.windowvisitAlert(but, but2, Gui.getProperties().getProperty("text"), Gui.getProperties().getProperty("text"));
}catch (Exception ex) {
sc.functionSavingInLog(Utils.getClassInfo(Thread.currentThread().getStackTrace()[1]), ex.toString());
System.out.println(Utils.getClassInfo(Thread.currentThread().getStackTrace()[1]) + ex);
}
}
This is actually not working so my question is:
-How can I make this condition work and make the JDialog close when it hits it?
If not, how can I change the method or just do a jpanel?
I have a program which uses 3 radiobuttons to switch between 3 incrementing values for a counter, here time.
I want to change status when a radiobutton is pressed, and it does so, but only for a fraction. When launching the program will keep printing
0
Normal
2
Normal
4
Normal
6
etc. When I press the button slow it prints CHANGE Slow once but keeps incrementing with 2 and still prints Normal every time.
How can I have this permenently switch to a different value for status, and a different increment, until I choose another radiobutton again?
package daynightcycle;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
/**
* Day/night cycle with visuals. Adjustable speed and time inserts.
* Optional date or daycounter later
* #author rogie
*/
public class DayNightCycle extends JFrame implements Runnable{
//JFrame entities
private JPanel animationPanel;
public JRadioButton button;
public JRadioButton button2;
public JRadioButton button3;
public int time = 0;
public String status = "Normal";
public static void main(String[] args) {
DayNightCycle frame = new DayNightCycle();
frame.setSize(2000, 1300);
frame.setLocation(1000,350);
frame.createGUI();
frame.setVisible(true);
frame.setTitle("Day/Night Cycle, Rogier");
(new Thread(new DayNightCycle())).start();
}
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout(new FlowLayout() );
animationPanel = new JPanel();
animationPanel.setPreferredSize(new Dimension(2000, 900));
animationPanel.setBackground(Color.black);
window.add(animationPanel);
JRadioButton option1 = new JRadioButton("Slow");
JRadioButton option2 = new JRadioButton("Normal", true);
JRadioButton option3 = new JRadioButton("Fast");
option1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("CHANGE");
status = "Slow";
System.out.println(status);
}
});
option2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
status = "Normal";
}
});
option2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
status = "Fast";
}
});
//option2.setFont(new java.awt.Font("Tahoma", Font.BOLD, 30));
//option2.putClientProperty("JComponent.sizeVariant", "huge"); //doesn't work
ButtonGroup group = new ButtonGroup();
group.add(option1);
group.add(option2);
group.add(option3);
add(option1);
add(option2);
add(option3);
pack();
}
public void run() {
while(true){
System.out.println(time);
System.out.println(status);
try
{
Thread.sleep(500);
if (status.equals("Slow")) {
time += 1;
}
else if (status.equals("Normal")){
time += 2;
}
else {
time += 3;
}
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
}
}
You are creating to DayNightCycle-Objects, the first shows the GUI and the second prints on the console.
Change the line
(new Thread(new DayNightCycle())).start();
to
(new Thread(frame)).start();
public static void main(String[] args) {
final DayNightCycle frame = new DayNightCycle();
frame.setSize(2000, 1300);
frame.setLocation(1000,350);
frame.createGUI();
frame.setTitle("Day/Night Cycle, Rogier");
And then
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});
Or in java 8:
EventQueue.invokeLater(() -> frame.setVisible(true));
}
You in effect created a second DayNightCycle.
Hello while I was following a tutorial I have learnt a way to trigger response in the main class from a click of a button in another class.
So what I have done is that I have a ToolBar class with some code as below
private JButton helloButton;
private JButton goodbyeButton;
private StringListener textListener;
public Toolbar() {
setBorder(BorderFactory.createEtchedBorder());
helloButton = new JButton("Hello");
goodbyeButton = new JButton("Goodbye");
helloButton.addActionListener(this);
goodbyeButton.addActionListener(this);
setLayout(new FlowLayout(FlowLayout.LEFT));
add(helloButton);
add(goodbyeButton);
}
public void setStringListener(StringListener listener) {
this.textListener = listener;
}
#Override
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton) e.getSource();
if (clicked == helloButton) {
if (textListener != null){
textListener.textEmitted("Hello\n");
}
//textPanel.appendText("Hello\n");
} else {
if (textListener != null){
textListener.textEmitted("Goodbye\n");
//textPanel.appendText("Goodbye\n");
}
}
}
Then in StrinListener Interface I have
public interface StringListener {
public void textEmitted (String text);
}
Finally in main I get the two together by
toolbar.setStringListener(new StringListener (){
#Override
public void textEmitted(String text) {
textPanel.appendText(text);
}
});
what I am curious about is that why does clicking a button trigger response in main method "every time" I click?
so the click is being passed onto textemitted method in StringListener interface and that is received by toolbar.setStringListener in main method. But what is invoking it to work over and over whenever I click the button?
shouldn't the code be read only once unless there is while loop or another loop of some sort?
Thanks
my main class
public MainFrame() {
super("Hello World");
setLayout(new BorderLayout());
textPanel = new TextPanel();
btn = new JButton("Click Me!");
toolbar = new Toolbar();
formPanel = new FormPanel();
toolbar.setStringListener(new StringListener (){
#Override
public void textEmitted(String text) {
textPanel.appendText(text);
}
});
formPanel.setFormListener(new FormListener(){
public void formEventOccurred(FormEvent e){
String name = e.getName();
String occupation = e.getOccupation();
textPanel.appendText(name + ": " + occupation + "\n");
}
});
add(toolbar, BorderLayout.NORTH);
add(textPanel, BorderLayout.CENTER);
add(formPanel, BorderLayout.WEST);
setSize(600, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
It is behaving as expected.
Remember that when you set the textListener, the Toolbar class holds on to an instance variable (of the textListener), and therefore it is kept alive as long as your program is running or until the toolbar object is destroyed. Just because it is an anonymous inner class doesn't mean that the object is destroyed after the method textEmitted is ran once.
sorry to bother everyone.
Overall problem: I'm trying to open a dialogue box let the user enter something then close it
Issue: - A function is not being called (i think)
- The main problem is when i use debug it works fine so Its difficult for me to track down the problem
I'm having trouble with JButtons,
it works in debug but not in normal run. this was probably because i was using an infinite loop. someone online suggested i used SwingUtilities but that didn't work (at least i don't think.
/**
*
* #author Deep_Net_Backup
*/
public class butonTest extends JFrame {
String name;
boolean hasValue;
//name things
private JLabel m_nameLabel;
private JTextField m_name;
//panel
private JPanel pane;
//button
private JButton m_submit;
//action listener for the button submit
class submitListen implements ActionListener {
public void actionPerformed(ActionEvent e) {
submit();
System.out.println("Test");
}
}
//constructor
public butonTest(){
//normal values
name = null;
hasValue = false;
//create the defauts
m_nameLabel = new JLabel("Name:");
m_name = new JTextField(25);
pane = new JPanel();
m_submit = new JButton("Submit");
m_submit.addActionListener(new submitListen());
//
setTitle("Create Cat");
setSize(300,200);
setResizable(false);
//add components
pane.add(m_nameLabel);
pane.add(m_name);
pane.add(m_submit);
add(pane);
//last things
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
//submit
private void submit()
{
System.out.println("submit");
name = m_name.getText();
hasValue = true;
}
//hasValue
public boolean hasValue()
{
return(hasValue);
}
//get the text name
public String getName()
{
return(name);
}
public void close()
{
setVisible(false);
dispose();
}
public static void main(String[] args)
{
/* Test 1
boolean run = true;
String ret = new String();
butonTest lol = new butonTest();
while(run)
{
if(lol.hasValue())
{
System.out.println("Done");
run = false;
ret = new String(lol.getName());
lol.close();
}
}
System.out.println(ret);*/
//Tset 2
/*
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
butonTest lol = new butonTest();
if(lol.hasValue())
{
System.out.println(lol.getName());
}
}
});*/
}
}
Edit:
How its not working: When i run Test the program will print test and submit then it should change the hasValue to true. this will (hopefully) allow the if statement to run to print done. This does not happen.
Edit 2:
I have just added a few more lines for further testing 2 prints and this seems to have solved the issue (but this is bad)
System.out.println("hasValue " + hasValue); -> to the hasValue() function
System.out.println("set to true"); -> submit() function
You are doing something far too complicated than is necessary. Instead of having the listener as a seperate class, you could have it as an anonymous class. That way you can get a handle on the outer class (butonTest.this), and call any method you want on it.
m_submit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
submit();
System.out.println("Test");
butonTest.this.close();
}
});
I'm not sure what you are trying to do with the infinite loop. It would have run to completion before you show the dialog anyway.
It would help to read up a bit on how Event-Handling works in Swing :)
I am afraid your constructor butonTest() and submit() method are out of your
class (public class butonTest extends JFrame).
you need to get them inside your class: