I have problem understanding how is actionListener used in the following code and what is the addWindowListener method doing in the code below:
kindly help me with it .
public class SwingListenerDemo {
private JFrame mainFrame;
private JLabel statusLabel;
public SwingListenerDemo(){
prepareGUI(); }
public static void main(String[] args){
SwingListenerDemo swingListenerDemo = new SwingListenerDemo();
swingListenerDemo.showActionListenerDemo();}
private void prepareGUI(){
mainFrame = new JFrame("Java SWING Examples");
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
mainFrame.setVisible(true);
}
private void showActionListenerDemo(){
JButton okButton = new JButton("OK");
okButton.addActionListener(new CustomActionListener());
mainFrame.add(okButton);
mainFrame.setVisible(true); }
class CustomActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
statusLabel.setText("Ok Button Clicked.");
}
}
}
When you click on ok button, your actionPerformed method will get called as you registered callback on ok button as okButton.addActionListener(new CustomActionListener());
When you close your awing window from top right 'X' button, your program will exit with a return code of 0 and that's what your window listener is doing in windowClosing method.
Related
I'm trying to change button action in a subclass because the form is pretty much exactly the except one asks for an ID. What I i tried doing was making a ActionListener object and instantiating it to an object of an anonymous class like so:
class ParentClass extends JPanel{
JButton button;
ActionListener buttonAction;
ParentClass{
button = new JButton("Parent Action");
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the parent class");
}
};
button.add(buttonAction);
add(button);
}
}
class ChildClass extends ParentClass{
JButton button;
ActionListener buttonAction;
ChildClass{
super();
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the child class");
}
};
}
}
public static void main(String[] args){
JFrame frame = new JFrame;
frame.add(new ChildClass());
frame.setSize(600, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
I was trying to use this method but the actionPerformed of buttonAction is never called. How can I make the button action different for the parent class and the subclass?
You can let parent class implement ActionListener, then use button.addActionListener(this) in order to add the action to button. Then in the subclass #Override actionPerformed method:
class ParentClass extends JPanel implements ActionListener
{
ParentClass()
{
JButton button = new JButton("something");
button.addActionListener(this);
add(button);
}
#Override
public void actionPerformed(ActionEvent event)
{
System.out.println("I am the parent.");
}
}
class SubClass extends ParentClass
{
SubClass()
{
super();//initialize button
}
#Override
public void actionPerformed(ActionEvent event)
{
System.out.println("I am the child.");
}
}
Another way is to add the ActionListener and inside it, only call a method. Something like buttonPressed. Then in subclass #Override buttonPressed method.
A complete example:
public class Test extends JFrame {
public Test() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(2, 1));
add(new ParentPanel());
add(new ChildPanel());
pack();
setLocationByPlatform(true);
}
private class ParentPanel extends JPanel implements ActionListener {
public ParentPanel() {
super(new BorderLayout());
JButton button = new JButton("My Class:" + getClass());
button.addActionListener(this);
add(button);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Parent");
}
}
private class ChildPanel extends ParentPanel {
public ChildPanel() {
super();
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Child");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Test().setVisible(true));
}
}
I the method I posted works. The issue is if you don't remove and add the button to the subclass it doesn't change the action that will run
class ParentClass extends JPanel{
JButton button;
ActionListener buttonAction;
ParentClass{
button = new JButton("Parent Action");
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the parent class");
}
};
button.add(buttonAction);
add(button);
}
}
So in the subclass what you would do is this:
class ChildClass extends ParentClass{
JButton button;
ActionListener buttonAction;
ChildClass{
super();
buttonAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked by the child class");
}
};
button.removeActionListener(button.getActionListeners()[0]);
button.addActionListener(buttonAction);
}
}
I, however, do not know why but would like an explanation as to why buttonAction had to be re-registered.
I am really new to GUI, got a little problem when I was trying to study it.
Ok here is my code.
public class Sample implements ActionListener{
public void go() {
JButton button = new JButton("Click");
JFrame frame = new JFrame();
frame.getContentPane().add(button);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100,100);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
button.setText("Hello");
}
});
}
It keeps telling me that The method addActionListener(ActionListener) in the type AbstractButton is not applicable for the arguments (new ActionListener(){}). I don't get it because I remember I did it before and it could work.
......
I don't get an error but the action listener won't work because the action performed method of the ActionListener Interface needs to overriden.
button.addActionListener(new ActionListener() {
// add the annotation below
#Override
public void actionPerformed(ActionEvent e) {
button.setText("hello");
}
});
And typically you would build the JFrame in the main method. Later they added an Invoke Later runner that when the class extends JFrame it would create the window in a more object oriented manner.
public class App extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
JFrame frame = new App();
frame.setVisible(true);
} catch (Exception e){
e.printStackTrace();
}
}
});
}
public App(){
JButton button = new JButton("Click");
getContentPane().add(button);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(100,100);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) {
button.setText("hello");
}
});
}
}
I have two jframes,
I want to get value from opened another jframe to other opened jframe.
when click jframe1 open button showing jframe2 and type some text in text field and click ok button, text field value want to get jframe1 jlable. how to do this i tried but i can't find a way to do this.
Is this possible ?
Use a callback,
add this code to your project:
Define an interface
public interface ICallbackListener{
void onNewEvent(String msg);
}
add to jframe 2:
private ICallbackListener myListener;
public void addCallback(ICallbackListener myListener){
this.myListener = myListener;
}
...
if(myListener!=null){
myListener.onNewEvent("myMessage");
}
...
add to jframe 1:
private ICallbackListener myListener;
ICallbackListener i = new ICallbackListener() {
#Override
public void onNewEvent(String msg) {
// TODO Auto-generated method stub
}
};
public void setCallback( ){
jframe2.addCallback(myListener);
}
now, every thime the jframe2 call the interface method you will get asynchronous a call to the TODO label in the jframe1
Try This
import java.awt.FlowLayout;
import javax.swing.*;
import java.awt.event.*;
class TestFrameExample extends JFrame implements ActionListener{
static JLabel label ;
public static TestFrameExample test;
TestFrameExample()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
label = new JLabel("This is a label!");
JButton button = new JButton("Open");
button.setText("Press me");
button.addActionListener(this);
panel.add(label);
panel.add(button);
add(panel);
setSize(300, 300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void actionPerformed(ActionEvent a)
{
new TestFrameExample1();
}
public static void main(String s[]) {
test=new TestFrameExample();
}
}
class TestFrameExample1 extends JFrame implements ActionListener {
JTextField t;
TestFrameExample test;
public TestFrameExample1()
{
setSize(300, 300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(null);
t=new JTextField();
t.setBounds(100,20,150,20);
JButton button=new JButton("oK");
button.setBounds(100,50,100,30);
button.addActionListener(this);
add(t);
add(button);
}
public void actionPerformed(ActionEvent a)
{
test.label.setText(t.getText());
}
}
create a method that takes jframe1 in the jframe2
in the open button action event create a object from jframe2 and call that method that take jframe1.
so when u click Ok button in the jframe2 pass that text field value to the jframe1 object (that u passed to the jframe2) via a methdo
public class jframe1 {
public void actionPerformed(ActionEvent a){
jfame2 jf2 = new jframe2();
jf2.setJframe1(this);
}
public void updateLable(String value){
lblIdk.setText(value);
}
}
public class jframe2 {
private jframe1 jf1;
public void setJframe1(jframe1 jf1){
this.jf1 = jf1;
}
public void actionPerformed(ActionEvent a){
this.jf1.updateLable(txtidk.getText());
}
}
I have created custom button class which extends JComponent and want to add KeyListener on mouseEntered event (and later remove on mouseExited). So my goal is - when the mouse enters this JComponent - then if I press Enter - some code will be executed, related to only this button. How can I do that?
Use Key Bindings instead of KeyListeners, since the latter is way to low level for Swing. Just bring your mouse over the JButton, and then press ENTER, then take your mouse outside the bounds of the JButton and try pressing ENTER again. Have a look at this example and see if this is what you wanted :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonBinding {
private JPanel contentPane;
private JTextField tField;
private JButton button;
private KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");
private Action action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Action Performed");
contentPane.setBackground(Color.BLUE);
}
};
private MouseAdapter mouseActions = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent me) {
System.out.println("Mouse Entered");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "enter");
button.getActionMap().put("enter", action);
}
#Override
public void mouseExited(MouseEvent me) {
System.out.println("Mouse Exited");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "none");
contentPane.setBackground(Color.RED);
}
};
private void displayGUI() {
JFrame frame = new JFrame("Button Binding Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
tField = new JTextField(10);
button = new JButton("Click Me");
button.addMouseListener(mouseActions);
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new ButtonBinding().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
Lets say, we have a few JFrame windows visible in same time and for each window JDialog appears. When our windows in cascading mode and for dialogs setAlwaysOnTop is true then all dialogs will be visible over last window.
I just want to associate a Dialog component with its owner, so that when you'll be switching between Frames you'll get only one dialog on top and won't lose this dialog when click on a frame.
Dialogs have constructor like this:
setAlwaysOnTop(true);
setModal(false);
Thanks in advance!
How to make JDialog onTop only for his parent?
setParent in the constructor properly
have to use setModalityType f.e. ModalityType.DOCUMENT_MODAL ModalityType.APPLICATION_MODAL instead of setModal
setModal is valid to the container which intialized / is parent for this JDialog
don't to use more than one JFrame, use JDialog instead, reuse this container for another action
for example
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SuperConstructor extends JFrame {
private static final long serialVersionUID = 1L;
public SuperConstructor() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 300));
setTitle("Super constructor");
Container cp = getContentPane();
JButton b = new JButton("Show dialog");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
FirstDialog firstDialog = new FirstDialog(SuperConstructor.this);
}
});
cp.add(b, BorderLayout.SOUTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
System.exit(0);
}
});
add(bClose, BorderLayout.NORTH);
pack();
setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
SuperConstructor superConstructor = new SuperConstructor();
}
});
}
private class FirstDialog extends JDialog {
private static final long serialVersionUID = 1L;
FirstDialog(final Frame parent) {
super(parent, "FirstDialog");
setPreferredSize(new Dimension(200, 200));
setLocationRelativeTo(parent);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
JButton bNext = new JButton("Show next dialog");
bNext.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
SecondDialog secondDialog = new SecondDialog(parent, false);
}
});
add(bNext, BorderLayout.NORTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
private int i;
private class SecondDialog extends JDialog {
private static final long serialVersionUID = 1L;
SecondDialog(final Frame parent, boolean modal) {
//super(parent); // Makes this dialog unfocusable as long as FirstDialog is visible
setPreferredSize(new Dimension(200, 200));
setLocation(300, 50);
setModal(modal);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setTitle("SecondDialog " + (i++));
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
}
In the API one of JDialog constructor is JDialog(Dialog owner, boolean modal) which means that you can create a dialog and specify the parent container as well as the modality. In the modal section, setting it to true means that this dialog will be modal and you cannot access the parent window while the dialog is in display.
But again, you can use the setModal() method to accomplish the same.
just set the Model true and Just set Relativelocation(parent); and dont use setontop(true) for the JDialog.
and then if u back open that time u will get dialog ontop every time. but that will be differ when u Drag the Parent Frame.
I managed to solve this problem building a focus listener that does this job. You can then set this listener to the window you want the dialog stays always visible until is closed. Here is what worked for me:
public class WindowFocusListenerDialogFocus implements WindowFocusListener {
private JFrame _dialogFrame;
public WindowFocusListenerDialogFocus(JFrame dialogFrame) {
_dialogFrame = dialogFrame;
}
#Override
public void windowLostFocus(WindowEvent e) {
System.out.println("Focus lost!");
}
#Override
public void windowGainedFocus(WindowEvent e) {
System.out.println("Focus gained!");
_dialogFrame.toFront();
}
}