I'm studying AWT and swing, and I'm beginning with some simple GUIs to get the hang of it.I wrote the following code,which works fine until I try to close the application and it won't exit.
import java.awt.*;
import java.awt.event.*;
public class AWTCounter extends Frame{
private Button button;
private Label label;
private TextField txt;
private int count=0;
public AWTCounter(){
super("AWT Counter");
addWindowListener(new WindowListener(){
#Override
public void windowActivated(WindowEvent arg0) {}
#Override
public void windowClosed(WindowEvent arg0) {
System.out.println("closing time!");
System.exit(0);
}
#Override
public void windowClosing(WindowEvent arg0) {}
#Override
public void windowDeactivated(WindowEvent arg0) {}
#Override
public void windowDeiconified(WindowEvent arg0) {}
#Override
public void windowIconified(WindowEvent arg0) {}
#Override
public void windowOpened(WindowEvent arg0) {}
});
label = new Label();
add(label);
label.setText("Counter");
txt = new TextField();
txt.setEditable(false);
add(txt);
button = new Button("count");
add(button);
setSize(400,100);
setLayout(new FlowLayout());
setVisible(true);
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
++count;
txt.setText(Integer.toString(count));
}
});
}
public static void main(String [] args){
Thread t =new Thread(new Runnable(){
public void run(){
new AWTCounter();
}
});
t.start();
}
}
I "registered" the WindowListener in the source component (the AWTCounter in this case, which is a Frame) and implemented the only method I was going to use, but it never respond... any idea as to why it behaves like that?
thanks a lot guys!
See the API for Frame - for the WINDOW_CLOSING event: "If the program doesn't explicitly hide or dispose the window while processing this event, the window close operation is canceled." - if you move your logic into the windowClosing method the application should exit. A Swing JFrame is a bit more friendly (you can set the default closing behavior to exit on close if you wish to exit the application upon closing the JFrame without the need for the WindowListener).
Last but not least, I'd recommend creating your GUI on the EventDispatchThread. For instance:
public static void main(String [] args) throws Exception{
Runnable t = new Runnable(){
public void run(){
new AWTCounter();
}
};
SwingUtilities.invokeAndWait(t);
}
Try doing this:
#Override
public void windowClosing(WindowEvent event) {
System.exit(0);
}
Related
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
I would need to have a MouseListener active on a SwingX JXDatePicker component, enabling me to perform specific actions when the user clicks on the component.
Unfortunately the event is never triggered.
Hereby a small piece of code that reproduces the problem:
public class TestDummy4 extends JFrame implements MouseListener{
private static final long serialVersionUID = -2424758762078571430L;
public TestDummy4(){
super();
this.getContentPane().setLayout(new BorderLayout());
//Adds date picker
JXDatePicker dp = new JXDatePicker();
dp.getEditor().setEditable(false);
dp.getEditor().setHighlighter(null);
dp.addMouseListener(this);
this.getContentPane().add(dp);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) throws IOException {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Builds GUI
new TestDummy4();
}
});
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Mouse clicked");
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("Mouse pressed");
}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {
System.out.println("Mouse Entered");
}
#Override
public void mouseExited(MouseEvent e) {}
}
With this code, I have not a single line of output on the console when clicking on the JXDatePicker.
Any help / hint would be greatly appreciated!
Thomas
To add a MouseListener to the JXDatePicker's editor component use:
dp.getEditor().addMouseListener(this);
Update:
To add a ActionListener to the component's open JButton you can use:
JButton openButton = (JButton) dp.getComponent(1);
openButton.addActionListener(myActionListener);
I want to update my text area along with typing in the text field but i get a delay of 1 keystroke while typing i.e when i press a key the previous key is displayed.Here is my snippet
private void jTextField1KeyTyped(java.awt.event.KeyEvent evt)
{
String a = jTextField1.getText();
jTextArea1.setText(a);
}
I would not recommend using KeyListeners
Simply add a DocumentListener to your JTextField via:
textField.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent de) {
}
#Override
public void removeUpdate(DocumentEvent de) {
}
#Override
public void changedUpdate(DocumentEvent de) {
}
});
Inside each of the methods ( insertUpdate,removeUpdate and changedUpdate) simply put in a call to set the text of your JTextArea via setText():
textArea.setText(textField.getText());
Here is an example I made:
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test().createAndShowUI();
}
});
}
private void createAndShowUI() {
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents(frame);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
private void initComponents(JFrame frame) {
final JTextField jtf = new JTextField(20);
final JTextArea ta = new JTextArea(20,20);
ta.setEditable(false);
jtf.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent de) {
ta.setText(jtf.getText());
}
#Override
public void removeUpdate(DocumentEvent de) {
ta.setText(jtf.getText());
}
#Override
public void changedUpdate(DocumentEvent de) {
//Plain text components don't fire these events.
}
});
frame.getContentPane().add(jtf, BorderLayout.WEST);
frame.getContentPane().add(ta, BorderLayout.EAST);
}
}
You should do that under the keyReleased event instead of the keyTyped and it will work as you need.
You need to wait till the event on your TextField is processed before updating the TextArea. Your code update the TextArea before the TextField is done processing the new typed character. Hence the text set in the TextArea is one keystroke behind.
You could try using recursion by referencing the method inside the method (avoid loops though).
I want to be notified when my JPopupMenu is hidden — whether because an item was selected, the menu was dismissed, or setVisible(false) was called on it. Here is my test code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class A extends ComponentAdapter implements Runnable, ActionListener {
private JButton b;
public static void main(String[] args) {
EventQueue.invokeLater(new A());
}
public void run() {
JFrame f = new JFrame("Test");
b = new JButton("Click me");
b.addActionListener(this);
f.add(b);
f.pack();
f.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
JPopupMenu pm = new JPopupMenu();
pm.addComponentListener(this);
pm.add("Popup...");
pm.add("...menu!");
pm.show(b, 10, 10);
}
public void componentShown(ComponentEvent e) { System.out.println("componentShown"); }
public void componentHidden(ComponentEvent e) { System.out.println("componentHidden"); }
}
Regardless of how I interact with the menu, neither of the two ComponentListener methods are being called. Why is that? Is there different/better/correct way of finding out when my JPopupMenu is hidden?
Thanks,
Cameron
JPopupMenu has a special listener for visibility change events:
pm.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
System.out.println("cancelled");
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
System.out.println("vanishing");
}
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
System.out.println("appearing");
}
});
Note, however, as method names hint, they are called before visibility changes, so if you're calling isVisible() somewhere in the event handlers, you should be aware of that, for example:
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
updateMenu();
}
private void updateMenu() {
if (!menu.isVisible()) { // this won't work!
// perform some updates
}
}
With regards to why ComponentListener isn't sending you events on the menu disappearing, this might explain:
The component-hidden and component-shown events occur only as the result of calls to a Component 's setVisible method. For example, a window might be miniaturized into an icon (iconified) without a component-hidden event being fired.
Source: ComponentListener tutorial (non-canonical perhaps, but from the horse's mouth.)
Consider that in conjunction with JPopupMenu's implementation of setVisible:
public void setVisible(boolean b) {
// Not supported for MenuComponents
}
And you might know how it so happens, but not why it happens (what is the justification and where is that properly documented?)