I have some problems with using dispose() method in my GUI project.
I' am making a GUI swing application for some kind of Elections in IntelliJ.
My problem is, by clicking a button(Confirm1, or 2 or 3) I want to open new JFrame which is checking the age of voter and closes the current JFrame where this button is located by calling dispose().
But frame.dispose(); doesn't work.
I have my JFrame declared in public static main().
Should I make reference for it in my ActionListener? I have been looking for solution, but I couldn't find any.
Here is a code:
import javax.swing.*; //another libraries
public class ElectionGUI {
private JPanel labelElection; // another texfields or etc.
private JButton Confirm1;
private JButton Confirm3;
private JButton Confirm2;
private JPanel Elections;
public VotesGUI(){
Votes votes = new Votes("...","...",0);
listX.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()){
NrX.setText(listX.getSelectedValue().toString());
}
}
});
listY.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()){
NrY.setText(listY.getSelectedValue().toString());
}
}
});
listZ.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()){
NrZ.setText(listZ.getSelectedValue().toString());
}
}
});
Confirm1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
votes.VotesX();
votes.countVotes();
CheckAge age = new CheckAge();
age.Check(); /// referention, to my next //Jframe called psvm Check();
}
});
Confirm2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
votes.VotesY();
votes.countVotes();
CheckAge age = new CheckAge();
age.Check();
}
});
Confirm3.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
votes.VotesZ();
votes.countVotes();
CheckAge age = new CheckAge();
age.Check();
}
});
}
public static void main(String[] args) {
JFrame frame = new JFrame("Elentions");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setContentPane(new ElectionGUI().labelElection);
frame.pack();
}
}
I want to initialize a Graphical User Interface (GUI) for the user to input a form. After this is accomplished i want to open a new GUI, but as soon as the first GUI pops-up the next one is initialized to.
Is there any way to solve this without using waits and notifies?
here is an example of my code:
public static void main(String[] args) {
new GUIForm();
// wait until the user inputs the complete form
new GUIWelcome();
}
It is really simple I woild like to keep it that way.
Create an Interface OnActionListener
public interface OnActionListener {
public void onAction();
}
Add these code in GUIForm class
private OnActionListener listener;
private JButton action;
public GUIForm(OnActionListener listener) {
this.listener = listener;
action = new JButton("Action");
action.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GUIForm.this.listener.onAction();
}
});
}
Now you can achieve that
new GUIForm(new OnActionListener() {
#Override
public void onAction() {
new GUIWelcome();
}
});
You need to use some sort pub/sub mechanism. This in a nutshell is what you need:
public class PubSub {
public static void main(String[] args) {
JFrame frame1 = new JFrame("GUIForm");
frame1.setSize(640, 480);
JButton button = new JButton("User Input");
JFrame frame2 = new JFrame("Welcome");
frame2.setSize(320, 240);
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
button.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
#Override
public void mouseExited(MouseEvent e) {
button.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
#Override
public void mouseClicked(MouseEvent e) {
frame2.setVisible(true);
}
});
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.add(button);
frame1.setVisible(true);
}
}
This version uses JFrame's listeners, but you could implement your on callback mechanism to accomplish the same
The program hangs after trying to construct another instance of itself when I wait for the reference returned by the constructor to be set.
If I click on the button, the program will hang.
edit: removed silly second wait loop.
edit 2: change true to false when calling constructor. program seems to work now.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
public class Problem extends JPanel {
public Problem(boolean wait) {
frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
if(wait) try {
System.out.println("calling invoke and wait");
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
Problem.this.run();
}
});
} catch(InvocationTargetException|InterruptedException e) {
throw new RuntimeException(e);
}
else {
System.out.println("calling invoke later");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Problem.this.run();
}
});
}
}
public String title() {
return "title";
}
public void addContent() {
JButton button=new JButton("click");
add(button,BorderLayout.CENTER);
button.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent arg0) {
Runnable runnable=new Runnable() {
#Override public void run() {
System.out.println("before new "+Thread.currentThread());
problem=new Problem(false);
System.out.println("after new "+Thread.currentThread());
}
};
new Thread(runnable).start();
System.out.println("before first wait "+Thread.currentThread());
while (problem==null)
;
}
});
}
void run() {
frame.setTitle(title());
frame.getContentPane().add(this,BorderLayout.CENTER);
addContent();
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new Problem(false);
}
Problem problem;
public final JFrame frame;
private static final long serialVersionUID=1;
}
p1 = problem instance from main function
State 1: Creation - p1 is initialized. p1.problem is null
State 2: User clicks button. Eventually, in another thread, p1.problem is created. However, p1.problem.problem had never been initialized and won't be until the user clicks a button, which will never happen. I'm not sure what you're trying to do but it seems like your program is hanging on while (problem.problem==null);
as I said in other posts I'm new in Java and I'm having some dumb problems, here's the deal:
I have a radioButton (radioStock) and a textField (stockField). I want stockField to be setEnabled(false) by default, no problem with that, and whenever the radioStock is checked, set the stockField enabled on true. I wrote this code, but it doesn't work.
if (radioStock.isSelected()) {
stockField.setEnabled(true);
}else{
stockField.setEnabled(false);
}
That code needs to be in a listener that is attached to the JRadioButton such as an ActionListener or ItemListener. And you don't even need the if blocks since all you'd need is one line of code inside of the listener:
radioStock.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent itemEvent) {
stockField.setEnabled(itemEvent.getStateChange() == ItemEvent.SELECTED);
}
});
For more on use of JRadioButtons, please check out the tutorial: button tutorial.
Edit my SSCCE
import java.awt.event.*;
import javax.swing.*;
public class ItemListenereg {
private static void createAndShowGui() {
final JRadioButton radioStock = new JRadioButton("Stock", true);
final JTextField stockField = new JTextField(10);
JPanel panel = new JPanel();
panel.add(radioStock);
panel.add(stockField);
radioStock.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent itemEvent) {
stockField.setEnabled(itemEvent.getStateChange() == ItemEvent.SELECTED);
}
});
JOptionPane.showMessageDialog(null, panel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This should work
radioStock.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(radioStock == e.getSource())
{
stockField.setEnabled(radioStock.isSelected());
}
}
});
I wonder how one should implement an event which will do some Action when a button is pressed, and stop do that action when button is released
I tried to add MouseListerner for this approach. The problem is it will recognize that I have pressed the button. But not which button it is. So wonder how should it be written so it will know which button I have pressed down.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Main extends JFrame implements MouseListener, ActionListener{
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel(new GridLayout(4,4));
public Main() {
setSize(300,400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(panel1, BorderLayout.NORTH);
add(panel2, BorderLayout.CENTER);
String[] buttonNamn = {"1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
for(int i=0;i<buttonNamn.length;i++) {
JButton button = new JButton(buttonNamn[i]);
panel2.add(button);
button.addMouseListener(this);
button.addActionListener(this);
}
}
public static void createGUI() {
new Main();
}
public static void main(String[] args) {
createGUI();
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
System.out.println("Pressed");
}
#Override
public void mouseReleased(MouseEvent arg0) {
System.out.println("Relased");
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("1")) {
System.out.println("Foo 1");
}
else if(e.getActionCommand().equals("2")){
System.out.println("Foo 2");
}
}
}
You will need invokeLater as described here: Java: mytextarea.setText("hello") + Thread.sleep(1000) = strange result
otherwise your action will block the UI-thread
For the start look at SwingUtilities.invokeLater.
For the cancel, I generally use an interface with a cancel operation on it which the Runnable provided to the invokeLater implements, the cancel button then kicks off the cancel simply by calling the cancel operation. How this cancels teh operation depends on what it does, maybe it could set a cancelled flag which the running operation can periodically check to see if it should continue.
Note that you can extend listener implementation classes like MouseAdapter to save yourself some typing (only override the methods you want to use).
Rather than use a single listener and have a bunch of case statements to try and figure out the relationship between the button and the data, add a new listener to each button and hold the data in the listener. This code does this with an anonymous class.
public static void main(String[] args) {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(4, 4));
String[] buttonName = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "A",
"B", "C", "D", "E", "F" };
for (final String name : buttonName) {
JButton button = new JButton(name);
panel.add(button);
button.addMouseListener(new MouseAdapter() {
#Override public void mousePressed(MouseEvent e) {
System.out.println("pressed:" + name);
}
#Override public void mouseReleased(MouseEvent e) {
System.out.println("released:" + name);
}
});
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}
Note the use of the final keyword.
There are other ways to express this, if you prefer. This method adds a static inner class:
private static class MyListener extends MouseAdapter {
private final String name;
public MyListener(String name) {
this.name = name;
}
#Override public void mousePressed(MouseEvent e) {
System.out.println("pressed:" + name);
}
#Override public void mouseReleased(MouseEvent e) {
System.out.println("released:" + name);
}
}
public void addStaticInnerClassListener(JButton button, String name) {
button.addMouseListener(new MyListener(name));
}
This one uses a class scoped to the method:
public void addNameListener(JButton button, final String name) {
class MyListener extends MouseAdapter {
#Override public void mousePressed(MouseEvent e) {
System.out.println("pressed:" + name);
}
#Override public void mouseReleased(MouseEvent e) {
System.out.println("released:" + name);
}
}
button.addMouseListener(new MyListener());
}
The code/action you want performed will have to be performed in another thread. Swing provides some utility classes for this, such as SwingWorker.
The getSource method of MouseEvent inherited from EventObject should give you a reference to the clicked button
java api link
Use MouseEvent.getButton() to get the button that triggered the event.