Which kind of listener do I have to add to a JFrame to detect when it is being hidden or shown via setVisible?
I tried using a WindowListener and the windowOpened and windowClosed methods, but they only work for the first time that a window is opened (windowOpened) or, respectively, when the window is closed using the dispose method (windowClosed). That is not enough for me. I want to be notified every time the window is made visible and invisible on the screen using setVisible.
Is there a standard Swing way to achieve this, or do I need to make my own (by, say, overriding the setVisible method)?
Try a java.awt.event.ComponentListener. You can add one using this code (where window is the name of the JFrame) :
window.addComponentListener(new ComponentAdapter() {
public void componentHidden(ComponentEvent e) {
/* code run when component hidden*/
}
public void componentShown(ComponentEvent e) {
/* code run when component shown */
}
});
1- Create a class that implements ComponentListener Interface, Like the following example:
//---------------------
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
public class winlistenner implements ComponentListener {
public void componentHidden(ComponentEvent arg0) {
// TODO Auto-generated method stub
System.out.print("Hided\r\n");
}
public void componentMoved(ComponentEvent arg0) {
// TODO Auto-generated method stub
System.out.print("Moved\r\n");
}
public void componentResized(ComponentEvent arg0) {
// TODO Auto-generated method stub
System.out.print("Resized\r\n");
}
public void componentShown(ComponentEvent arg0) {
// TODO Auto-generated method stub
System.out.print("Shown\r\n");
}
}
//------------------------------------------------------------------------
2- Now create a getter for your JFrame like this:
public class JMain {
private JFrame frmNetworkshareMoon;
private JTextField textField;
private JTextField textField_1;
private JTextField textField_2;
public JFrame getFrmNetworkshareMoon() {
return frmNetworkshareMoon;
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JMain window = new JMain();
winlistenner listenner= new winlistenner();
window.getFrmNetworkshareMoon().addComponentListener(listenner);
window.frmNetworkshareMoon.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
//......
// the rest of your class code:
//...
}
3- being your main like the above example, you will set JFrame listener the listener you created, and then run the program, you will see messages coming from the listener:
Moved
Resized
Resized
Moved
Shown
Moved
Moved
Related
I want to make a Swing program with icon tiles that play certain sounds when you click on them. For this I created the class:
public class Item extends JLabel implements MouseListener {
public Item(String s) {
// constructor setting background icon and private field with the sound to play
}
public void playSound(); //plays the sound
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Clicked");
this.playSound();
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("Pressed");
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Then I create a custom JFrame class:
public class Frame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 9221468315661092752L;
public static final int DEFAULT_FRAME_WIDTH=400;
public static final int DEFAULT_FRAME_HEIGHT=400;
private GridLayout gridLayout;
private ArrayList<Item> tiles=new ArrayList<Item>();
public Frame() {
super("Title");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(new Dimension(DEFAULT_FRAME_WIDTH,DEFAULT_FRAME_HEIGHT));
gridLayout=new GridLayout(4,4,10,10);
setLayout(gridLayout);
addItems();
}
public void addItems() {
Item item=new Item("name");
Item item2=new Item("name");
tiles.add(item);
tiles.add(item2);
this.add(item);
this.add(item2);
}
public static void main(String[] args) {
Frame frame=new Frame();
frame.setVisible(true);
}
The tiles show normally in the grid layout, however the problem is that the mouse listener doesn't work. The println() I put at mouseClicked() and mousePressed() is not called.
I could try to add a MouseListener to the Item class, so that Item has a MouseListener, but I wonder what is wrong with the above code.
You have two problems. One, your JLabels do not show (although I'm not sure if that was intentionally left out). Two, you never add a mouse listener. You can accomplish this by adding two statements to the constructor, without making any extra classes:
public Item(String s) {
super(s); //initializes the text and display using JLabel's constructor
addMouseListener(this); //uses the reference of this Item as a MouseListener
}
Button actionlistener. (r is the call method for my class i call it above Run r= new Run();. it sets the window invisible but when it's supposed to get it back visible the program closes without any errors. Tried instead of setVisible(false); dispose(); but same problem.
about.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JFrame a=new JFrame("About");
a.addWindowListener(new WindowListener(){
#Override
public void windowActivated(WindowEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void windowClosed(WindowEvent arg0) {
}
#Override
public void windowClosing(WindowEvent arg0) {
r.gui.setVisible(true);
}
#Override
public void windowDeactivated(WindowEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void windowDeiconified(WindowEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void windowIconified(WindowEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void windowOpened(WindowEvent arg0) {
r.gui.setVisible(false);
}
});
a.setSize(400, 400);
a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
a.setVisible(true);
a.setLayout(null);
JLabel lbl=new JLabel("This game was made by your lovely neighbourhood takisp22");
lbl.setSize(500,50);
lbl.setLocation(0,0);
a.setLocation(100,50);
a.add(lbl);
}
});
Other Class which runs the program:
import javax.swing.JFrame;
public class Run {
public static GameAim gui=new GameAim();
public static void main(String[] args){
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setTitle("Aim Training");
gui.setSize(1280, 800);
gui.setVisible(true);
gui.setLocation(100,50);
gui.setResizable(false);
gui.openFile();
gui.readFile();
gui.closeFile();
}
}
Because of this:
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
when you close the gui JFrame variable, the program exits.
Don't use this, but instead use JFrame.DISPOSE_ON_CLOSE. Having said this, please read: The Use of Multiple JFrames, Good/Bad Practice?. Your user is not going to like to have multiple windows shoved at them. Swap views instead with a CardLayout -- tutorial link.
We'll also need to discuss the evils of your use of a.setLayout(null); at some time.
;)
I have a simple login frame with a JTextField and a JPasswordField. When my frame loads the text of the JTextField is "Typ your login". I want to erase that text when the JTextField gets focus. It's the first element in my frame so it already has focus when I load the frame, but I want it to clear whenever I click on it or start typing in it. I tried a MouseListener, which works fine, but now I'd like to clear the JTextField from the moment I start typing. This is the code involving my problem:
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class TextFields extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField login;
private JPasswordField password;
public TextFields() {
super("Event handling");
setLayout(new FlowLayout());
login = new JTextField("Type your login", 20);
password = new JPasswordField(20);
add(login);
add(password);
LoginHandler handler = new LoginHandler();
login.addMouseListener(handler);
}
private class LoginHandler implements ActionListener, MouseListener {
public void mouseClicked(MouseEvent e) {
login.setText("");
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void focusLost(FocusEvent arg0) {
// TODO Auto-generated method stub
}
}
public static void main(String[] args) {
TextFields test = new TextFields();
test.setDefaultCloseOperation(EXIT_ON_CLOSE);
test.setSize(250, 100);
test.setVisible(true);
}
}
I don't know the canonical answer, but I've used a FocusListener for this issue, by calling selectAll() in the focusGained method. Don't use a MouseListener since this will fail if the user tabs into the field.
e.g.,
private class MyFocusListener extends FocusAdapter {
#Override
public void focusGained(FocusEvent fEvt) {
JTextComponent component = (JTextComponent) fEvt.getSource();
component.selectAll();
}
}
and
login.addFocusListener(new MyFocusListener());
Conceptually, what you really want is to set a “placeholder” or “prompt” for your text field, rather than changing the actual text in the field. Such an abstraction would also give you features like being able to style the prompt a light gray color.
A normal JTextField does not support this, but you could write your own subclass, or use a library. This answer explains how to use the SwingX library to accomplish that. Basically, just import org.jdesktop.swingx.prompt.PromptSupport; and add this line:
PromptSupport.setPrompt("Type your login", login);
I have designed a panel that includes some buttons with it. Buttons are attached with an ActionListener. When ever i click on that buttons this ActionListener detects 4 events for this single click. Whereas it should detect only one. Does anybody know what exactly the reason is?
public class Buttons extends JPanel
{
private JButton undo=new JButton("Undo");
private JButton replay=new JButton("Replay");
public void paint(Graphics g)
{
super.paint(g);
super.setSize(new Dimension(560,30));
super.add(replay);
super.add(undo);
undo.setBorder(new LineBorder(Color.WHITE,3));
replay.setBorder(new LineBorder(Color.WHITE,3));
undo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
Controler.pieces.undo();
Controler.reDraw();
}
});
replay.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Dastiii");
}
});
}
}
and these events are being used here
public void undo()
{
System.out.print(Controler.allMoves.size());
if(Controler.allMoves.size()<=1)
{
init_board();
return;
}
Piece temp[][]=Controler.allMoves.get(Controler.allMoves.size()-2);
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
board[i][j].set_name(temp[i][j].get_name());
board[i][j].set_oneWay(temp[i][j].get_oneWay());
}
}
Controler.allMoves.remove(Controler.allMoves.size()-2);
}
Your registering you ActionListeners within the paint method!!
Let's not even worry about the fact that it's un-recommended to override paint
Never change or modify the state of the component or any of it's child components within in any paint method, these will be called multiple times during the execution of your application. For example, it's not unusual for a paint method to be called 2-4 times just when the main window is made visible...
public void paint(Graphics g)
{
super.paint(g);
/** All this should be done within the constructor
// If you are using a layout manager, this is pointless, if your not
// then that's another problem
super.setSize(new Dimension(560,30));
super.add(replay);
super.add(undo);
undo.setBorder(new LineBorder(Color.WHITE,3));
replay.setBorder(new LineBorder(Color.WHITE,3));
undo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
Controler.pieces.undo();
Controler.reDraw();
}
});
replay.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Dastiii");
}
});
**/
}
Take a look at:
Performing Custom Painting
Painting in AWT and Swing
For more details about how and what painting is in Swing
Say If i have two classes, in each class is a different JFrame, e.g JFrame A and JFrame B ( in seperate classes).
Now from the constructor of JFrame A I may push a button with an actionlistener attached, which will instantiate the other class, thus creating JFrame B. The problem is when JFrame B is created, both the JFrames are visible. If i close JFrame B, then JFrame A closes as well. How can i make it so only JFrame B closes?
Thanks
edit DISPOSE_ON_CLOSE does not work for me, it closes all the jframes.
some sample code:
public class classone {
public classone() {
JFrame a = new JFrame("this is A");
classtwo newFrame = new classtwo();
}
}
public class classtwo {
public classtwo() {
Jframe b = new JFrame("this is B");
b.setDefaultCloseOperation(b.DISPOSE_ON_EXIT);
}
}
please ignore any syntax errors, just for demonstration.
For the JFrame B, set the default close operation to "dispose" as shown below :
frameB.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Then closing the child windows won't shut down your entire application.
HTH ! ;-)
Do you have DISPOSE_ON_CLOSE on one frame and EXIT_ON_CLOSE on the other? If so then that would explain why your program is exiting prematurely. Ensure that all frames are set to DISPOSE_ON_CLOSE.
I got question now. Just when you create an instance of a Window tell how this object live, Review this code
...
new JFrame(){
#Override
public synchronized void addWindowListener(WindowListener l) {
// You may ask here also add windowClosing method and look at my previous post
super.addWindowListener(l);
}
}.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
....
Just DO_NOTHING_ON_CLOSE and addWindowListener in WindowClosing method show a JOptionPane.showConfirmDia and if result return no(1) then return; else system.exit(0);
its all
I see my first StackOverFlow post ,What a shame! I'm editting my post.here you are;
Until now , I realize Depending developing software approachs Swing getting older. I'm missing a technology like Microsofts XAML.
soyatec inc. has some deals using XAML with java you may have a look but "In my opinion" not successfull work.Anyway...
JFrame frame=new JFrame();
frame.addWindowListener(new WindowListener() {
#Override
public void windowClosing(WindowEvent e) {
int result= JOptionPane.showConfirmDialog(JOptionPane.getRootFrame() //or your parent swing element
, "Sure ?");
switch (result) {
case 1:
break;
default:
System.exit(0);
break;
}
}
#Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
#Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
}
);