Exiting JFrame when JButton is clicked - java

I am writing a Login GUI and want the cancel button to close the entire program when clicked. I'm a freshman computer science major and still semi-new to java and programming in general. Here is my code:
Main Class:
public class loginGui
{
public static void main(String[] args)
{
lGui gui = new lGui();
lGui.gui();
}
}
GUI class:
public class lGui
{
public static void gui()
{
JFrame frame;
JTextField field;
JLabel l;
JPasswordField p;
JButton login, cancel;
JCheckBox check;
frame = new JFrame("Login");
frame.setSize(300, 150);
frame.getContentPane().setBackground(Color.LIGHT_GRAY);
frame.setLocation(300, 200);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
l = new JLabel("Username: ");
l.setLocation(15, 14);
l.setSize(l.getPreferredSize());
frame.add(l);
field = new JTextField("Username");
field.setColumns(15);
field.setSize(field.getPreferredSize());
field.setBackground(Color.DARK_GRAY);
field.setForeground(Color.LIGHT_GRAY);
field.setLocation(90, 10);
field.setToolTipText("Enter User Name");
frame.add(field);
l = new JLabel("Password: ");
l.setLocation(15, 54);
l.setSize(l.getPreferredSize());
frame.add(l);
p = new JPasswordField("Password");
p.setColumns(15);
p.setSize(p.getPreferredSize());
p.setBackground(Color.DARK_GRAY);
p.setForeground(Color.LIGHT_GRAY);
p.setLocation(90, 50);
p.setToolTipText("Enter Password");
frame.add(p);
login = new JButton("Login");
login.setSize(login.getPreferredSize());
login.setLocation(195, 78);
login.setToolTipText("Login");
frame.add(login);
login.addActionListener(new loginAction());
cancel = new JButton("Cancel");
cancel.setSize(cancel.getPreferredSize());
cancel.setLocation(95, 78);
cancel.setToolTipText("Cancel");
frame.add(cancel);
cancel.addActionListener(new cancelAction());
check = new JCheckBox("Remember me?");
check.setSize(check.getPreferredSize());
check.setLocation(120, 100);
check.setToolTipText("Remember your username for next time");
frame.add(check);
frame.setVisible(true);
}
static class cancelAction implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
frame.dispose();
}
}
static class loginAction implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
}
}
}
I keep getting a "cannot find symbol" error here in the cancel button ActionListener:
frame.dispose();

frame only has context from within your static method gui. Start by getting rid of the static declaration and make frame an instance field of the class
public class lGui
{
private JFrame frame;
private JTextField field;
private JLabel l;
private JPasswordField p;
private JButton login, cancel;
private JCheckBox check;
public void gui()
{
//...
You also won't need the static declarations on the inner classes...
protected class cancelAction implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
frame.dispose();
}
}
protected class loginAction implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
}
}
You might find it easier to make initialise the UI from within the classes constructor instead of the gui method, leaving it to show the window
You should also avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
Instead, have a look at Laying Out Components Within a Container for some more ideas

The code in gui method has to be in a constructor and your JFrame object has to be defined outside of any methods, as a field of the class :)

Related

Method called from first JFrame does nothing in second

I set JTextField "rfid" to setEnabled(false) in MainGUI class and created method setRfidEnabled to be able to enable textfield from another class called CardLayout.
When I try to call it from CardLayout by button event listener it does nothing, I mean to textfield, because System.out.print("LOL"); works fine. MainGUI contains JFrame and by button calls another JFrame in CardLayout class.
When I initialize MainGUI class, it has Thread[Thread-2,6,main], but when I call CardLayout it becomes Thread[AWT-EventQueue-0,6,main], same as CardLayout itself. I tried to make "rfid" volatile, no success.
---Edited code---
MainGUI:
public class MainGUI {
JTextField rfid;
JButton button;
final JFrame frame;
final JPanel pane;
LayoutChanger layout = new LayoutChanger();
public MainGUI() {
rfid = new JTextField("", 10);
button = new JButton("CardLayoutSwitch");
frame = new JFrame("Main GUI Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout(5,5));
pane = new JPanel(new GridLayout(5, 5));
frame.add(pane,BorderLayout.CENTER);
pane.add(rfid);
pane.add(button);
rfid.setEnabled(false);
button.setEnabled(true);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent e){
layout.changeLayout(1);
}
});
}
public void setRfidEnabled() {
System.out.println("LOL");
rfid.setEnabled(true);
button.setEnabled(false);
}
}
LayoutChanger class:
public class LayoutChanger {
public static void main(String[] args) {
MainGUI gui = new MainGUI();
}
public void changeLayout(int i){
if (i == 1) {
CardLayout card = new CardLayout();
}
}
}
CardLayout class:
public class CardLayout {
JFrame frame;
JButton manual;
final JPanel pane;
MainGUI gui = new MainGUI();
public CardLayout() {
manual = new JButton("UID MANUAL");
frame = new JFrame("Card Scan Panel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new BorderLayout(5, 5));
pane = new JPanel(new BorderLayout(5, 5));
manual.setPreferredSize(new Dimension(50, 25));
frame.add(pane, BorderLayout.CENTER);
pane.add(manual);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
manual.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent e){
gui.setRfidEnabled();
}
});
}
}
As stated in the comments above by #matt
Every time you click on manual button, you're creating a new MainGUI().
You need to create a single instance, either in your constructor or in the ActionListener and ask if you already have an instance of it (i.e. a Singleton) and use it.
If you decide to use the first one, declare gui as a global variable:
MainGUI gui = new MainGUI();
And on your ActionListener have it changed as:
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(currentThread());
gui.setRfidEnabled();
//frame.dispose();
}
Then you have a single instance of it.
Also as stated by #Sergiy you don't really need all those threads
Here are some examples on how to use ActionListeners:
I'm trying to make a button to count characters in a text field
AppletViewer bugged and trying to involve a timer
Calculator returns 0.0 to all questions asked
Java - My action event doesn't work
Drawing shapes on a JForm java
Animated Sprites with Java Swing This one includes a Timer (Another thread that handles the animation but doesn't block the EDT)
As you can see in all the above examples, none of them required another Thread to handle the actions, the one that uses a thread is only for performing the animation and not to react to user clicks.
Recommended tutorial: How to use Actions

Calling different screen thru button from a screen

Hello I would like to ask how can I call my Main menu screen from MainScreen? and kindly explain a little more details about Listener.
below is my prepared code:
public class MainScreen {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
JLabel WelcomeNote = new JLabel("Welcome");
panel.add(WelcomeNote);
JButton Start = new JButton("Start");
panel.add(Start);
//Insert action for Start button here
}
}
public class MainMenu {
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(panel);
frame.setVisible(true);
}
private static void placeComponents(JPanel panel) {
JLabel menuLbl = new JLabel("Main Menu");
panel.add(menuLbl);
}
}
What is wrong?
You cannot have two main methods in a single file in Java.
Program
Here is a demo program to change windows.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class First extends JFrame
{
JLabel jlb = new JLabel("Label in First Window");
JButton jb = new JButton("Next Window");
First()
{
super("First Windows");
//Set this frame
this.setSize(350,250);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Setting size of components
jlb.setBounds(10,10,200,40);
jb.setBounds(10,120,150,40);
add(jlb);
add(jb);
jb.addActionListener((e)->{
this.setVisible(false);
new Second();
});
setVisible(true);
}
}
class Second extends JFrame implements ActionListener
{
JLabel jlb = new JLabel("Label in Second Window");
JButton jb = new JButton("Prev. Window");
Second()
{
super("Second Window");
this.setSize(350,250);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Setting size of components
jlb.setBounds(10,10,200,40);
jb.setBounds(10,120,150,40);
add(jlb);
add(jb);
jb.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
this.setVisible(false);
new First();
}
}
class StartHere
{
public static void main(String[] args) {
Runnable r = ()->{
new First();
};
r.run();
}
}
Understanding the above program.
The StartHere class has a main method. It is just used for calling the first window you like. I could even call Second using new Second().
First and Second are similar codes.
Both of them have buttons. On each button (or JButton) I have added a method named addActionListner(this). This method fires up an ActionEvent which as you can see in Second class is captured by actionPerformed method. This method is declared in Functional Interface, ActionListener. The 'this' passed in Second class is you telling where the actionPerformed method is present in your code. The parameter is an ActionListener. Hence, you have to implement ActionListener for the class where you define actionPerformed.
Bonus
The First class doesn't seem to follow the norms described above. I passed a strange syntax. It is a new feature included in Java 8.
See this Oracle tutorial about Lambda Expressions.

How to pass JTextField from JFrame into another JFrame?

I have two JFrame (JFrame1 and JFrame2) with two JTextField1 and JTextField2. My question is when I write "Hello world " on JTextField2 from Jframe2 and then click on OK button, I see "Hello world " on JTextField1 on Jframe1 class.
How can I do this? I'm sorry if this is a newbie question but I'm learning..
Here is my code:
JFrame2:
private JFrame1 jf1;
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.setjTextField1(this.jTextField2);
}
What you are doing there is actually sending the reference to the actual JTextField from one frame to the other one.
That's probably not a good idea cause both frames would be end up referencing the same visual component.
What you probably want is to keep all visual components separate, but make the text of the second text field equal to the text in the first one.
Something like this:
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.getjTextField1().setText(this.jTextField2.getText());
}
You could use an Observer Pattern or Producer/Consumer Pattern to solve the problem.
The basic idea is, you have something that generates a value and something that either wants to be notified or consume the generated value.
One of the other prinicples you should take the time to learn is also Code to interface (not implementation). This sounds stranger then it is, but the the idea is to reduce the unnecessary exposure of your objects (to unintended/controlled modifications) and decouple your code, so you can change the underlying implementation without affecting any other code which relies on it
Given the nature of your problem, an observer pattern might be more suitable. Most of Swing's listener's are based on the same principle.
We start by defining the contract that the "generator" will use to provide notification of changes...
public interface TextGeneratorObserver {
public void textGenerated(String text);
}
Pretty simple. This means we can safely provide an instance of any object that implements this interface to the generator and know that it won't do anything to our object, because the only thing it knows about is the textGenerated method.
Next, we need something that generates the output we are waiting for...
public class GeneratorPane extends JPanel {
private TextGeneratorObserver observer;
private JTextField field;
private JButton button;
public GeneratorPane(TextGeneratorObserver observer) {
this.observer = observer;
field = new JTextField(10);
button = new JButton("OK");
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
observer.textGenerated(field.getText());
}
};
button.addActionListener(listener);
field.addActionListener(listener);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(2, 2, 2, 2);
add(field, gbc);
add(button, gbc);
}
}
This is just a simple JPanel, but it requires you to pass a instance of TextGeneratorObserver to it. When the button (or field) triggers the ActionListener, the ActionListener calls the textGenerated to notify the observer that the text has been generated or changed
Now, we need someone to observer it...
public class ObserverPanel extends JPanel implements TextGeneratorObserver {
private JLabel label;
public ObserverPanel() {
label = new JLabel("...");
add(label);
}
#Override
public void textGenerated(String text) {
label.setText(text);
}
}
This is a simple JPanel which implements the TextGeneratorObserver interface and updates it's JLabel with the new text
Then, we just need to plumb it together
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
ObserverPanel op = new ObserverPanel();
op.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));
GeneratorPane pp = new GeneratorPane(op);
pp.setBorder(new CompoundBorder(new LineBorder(Color.GREEN), new EmptyBorder(10, 10, 10, 10)));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 1));
frame.add(pp);
frame.add(op);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
This is a complete working example I just coded out:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class FrameRunner
{
public static void main(String[] args){
MyFrame f1 = new MyFrame("Frame 1");
MyFrame f2 = new MyFrame("Frame 2");
f1.addRef(f2);
f2.addRef(f1);
}
}
class MyFrame extends JFrame{
JTextField txt = new JTextField(8);
JButton btn = new JButton("Send");
MyFrame f = null;
public MyFrame(String title){
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new FlowLayout());
setPreferredSize(new Dimension(400, 300));
setVisible(true);
add(btn);
add(txt);
pack();
setLocationRelativeTo(null);
init();
}
public void addRef(MyFrame f){
this.f = f;
}
public void init(){
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
f.update(txt.getText());
}
});
}
public void update(String str){
txt.setText(str);
}
}
In order to make the code short and easier for you to understand. Many of the things I did not following the conventions and I did not modularize the codes. But this should give you a very good idea of how you can pass in the reference of another JFrame.
This code shows an example of how Frame1 has a reference on Frame2. Yet Frame2 also has a reference on Frame1.
Whatever things you type in JFrame1 can be send to JFrame2's textfield. Same for the other way round.

How can I inform the class which have an instance of a GUI builder class, when the JButton ActionEvent performed

Ok, here is my problem. Class B is a class that build a GUI ,which has a textField and button. class A has an instance of class B.Now I enter some value in the textfield, when I click the button, in class A I want to print out the value I just enter in the textfield, how can I achieve that?
Code below may better explain what I want to achieve:
public class A
{
B myB = new B();
(when the JButton was clicked,
how can I get the new textfield value here?)
}
public class B
{
JLabel myLabel;
JButton myButton;
public B()
{
getContentPane().setLayout(null);
myLabel = new JLabel();
myLabel.setLocation(0,0);
myLabel.setSize(100,30);
myLabel.setBackground( new Color(-6710887) );
myLabel.setText("");
getContentPane().add(myLabel);
myButton = new JButton();
myButton.setLocation(0,50);
myButton.setSize(100,30);
myButton.setBackground( new Color(-16737895) );
myButton.setText("Submit");
getContentPane().add(myButton);
myButton.addActionListener(this);
setSize(400,400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
(how can I pass this "myLabel.getText()" value to class A when
this action performed?)
}
}
Can anybody help me finish this little program? Thanks in advance!
You need to expose the value in text field with a method in class B. Then class A can call that method. What it actually sounds like though is that class A (or something else) should be a ActionListener for your button.
However, a bigger problem is that you don't have a text field you just have a label in class B. This code is a good reason why you shouldn't use a GUI builder, especially when learning Swing.
Some reading:
http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html
http://docs.oracle.com/javase/tutorial/uiswing/events/
I often make an "App" class that ties all my GUI-builder-built components together. Any GUI builder worth anything lets you add getters to the generated source code. Add some getters to the GUI-built components to retrieve key elements of the GUI, then let the App class use the getters to interact with the components as necessary. This won't win any MVC/MVVM/MVP design awards, but it gets the job done, which ought to count for something.
public class App {
private B _b;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
App app = new App();
app.run();
}
});
}
void run() {
_b = new B();
_b.getMainButton().addActionListener(new MainButtonListener());
_b.setVisible(true);
}
private void handleMainButtonClicked() {
String mainText = _b.getMainTextArea().getText();
System.out.println("Button clicked; main text = " + mainText);
}
public class MainButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
handleMainButtonClicked();
}
}
}
public class B extends JFrame {
private JPanel _contentPane;
private JTextArea _jTextArea;
private JButton _jButton;
public B() {
initComponents();
}
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
_contentPane = new JPanel();
setContentPane(_contentPane);
_jTextArea = new JTextArea();
_contentPane.add(_jTextArea, BorderLayout.CENTER);
_jButton = new JButton("My Button");
_contentPane.add(_jButton, BorderLayout.SOUTH);
}
public JButton getMainButton() {
return _jButton;
}
public JTextComponent getMainTextArea() {
return _jTextArea;
}
}

Using AWT Buttons and detecting if clicked

I just joined, and am glad to be here~ So, this morning (at like 2am, but thats besides the point :P ) I was doing a little bit of Java tests with JFrame and other GUI stuff. This is my first time working with GUIs. I was trying to make a little java app that would act as a dream journaller. However, my progress was frozen when I encountered a problem i could not solve. My code is as follows.
import java.awt.*;
import javax.swing.*;
import java.applet.*;
public class Display extends Canvas
{
static final int WIDTH = 600;
static final int HEIGHT = 400;
public static String defaultEntry = "Dreams...";
public static final String TITLE = "Dream Journal Testing";
Button erase;
public static void main(String[] args)
{
Display d = new Display();
d.create();
}
public void create()
{
JFrame frame = new JFrame();
System.out.println("Running");
Panel cardOne = new Panel();
Panel p1 = new Panel();
Panel p2 = new Panel();
Panel p3 = new Panel();
Panel grid = new Panel();
cardOne.setLayout(new BorderLayout());
p1.setLayout(new GridLayout(2,1,3,6));
TextArea textArea1 = new TextArea(defaultEntry);
/*Font f1 = new Font("Courier", Font.PLAIN, 16);
setFont(f1);*/
Label l1 = new Label("Welcome to the Dream Journal! :)");
Label l2 = new Label("Type your dream below:");
p1.add(l1);
p1.add(l2);
p2.add(textArea1);
p3.setLayout(new FlowLayout(FlowLayout.CENTER));
Button ok = new Button("Save");
erase = new Button("Erase");
p3.add(erase);
p3.add(ok);
cardOne.add("North",p1);
cardOne.add("Center",p2);
cardOne.add("South",p3);
frame.add(cardOne);
//frame.add(cardOne);
//frame.setLocationRelativeTo(null);
frame.pack();
frame.setTitle(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(textArea1.getText());
}
/*public boolean handleEvent(Event evt)
{
if(evt.target == erase)
{
System.out.println("it works");
return true;
}
else return super.handleEvent(evt);
}
*/
public boolean action(Event evt, Object arg)
{
if("Erase".equals(arg))
{
System.out.println("hello");
//textArea1.setText("");
}
return true;
}
}
The problem i have is I am not able to figure out how to make it so if the "Erase" AWT button is pushed, the system will print a line (as a test). I have tried
public boolean action(Event evt, Object arg)
And
public boolean handleEvent, but neither worked. Anyone have any suggestions for the Java noob that is me? Thanks!! :)
One way is to add an action listener to the button (e.g. for Save). Another way is to create an Action (e.g. for Erase).
Don't mix Swing with AWT components unless it is necessary. It is not worth even learning how to use AWT components at this point in time, use Swing only for best results and best help.
Here is a version of the app. using all Swing components.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Display
{
static final int WIDTH = 600;
static final int HEIGHT = 400;
public static String defaultEntry = "Dreams...";
public static final String TITLE = "Dream Journal Testing";
JButton erase;
public static void main(String[] args)
{
Display d = new Display();
d.create();
}
public void create()
{
JFrame frame = new JFrame();
System.out.println("Running");
JPanel cardOne = new JPanel();
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
cardOne.setLayout(new BorderLayout());
p1.setLayout(new GridLayout(2,1,3,6));
JTextArea textArea1 = new JTextArea(defaultEntry);
JLabel l1 = new JLabel("Welcome to the Dream Journal! :)");
JLabel l2 = new JLabel("Type your dream below:");
p1.add(l1);
p1.add(l2);
p2.add(textArea1);
p3.setLayout(new FlowLayout(FlowLayout.CENTER));
JButton ok = new JButton("Save");
ok.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Do " + ae.getActionCommand());
}
});
erase = new JButton(new EraseAction());
p3.add(erase);
p3.add(ok);
// Use the constants
cardOne.add(BorderLayout.PAGE_START,p1);
cardOne.add(BorderLayout.CENTER,p2);
cardOne.add(BorderLayout.PAGE_END,p3);
frame.add(cardOne);
frame.pack();
frame.setTitle(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(textArea1.getText());
}
}
class EraseAction extends AbstractAction {
EraseAction() {
super("Erase");
}
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Do " + arg0.getActionCommand());
}
}
First let me explain you the Funda of Event Handler....
- First of all there are Event Source, when any action take place on the Event Source, an Event Object is thrown to the call back method.
- Call Back method is the method inside the Listener (Interface) which is needed to be implemented by the Class that implements this Listener.
- The statements inside this call back method will dictate whats needed to be done, when the action is done on the Event Source.
Eg:
Assume
Event Source - Button
When Clicked - Event object is thrown at the call back method
Call back method - actionPerformed(ActionEvent e) inside ActionListener.
Now your case :
Now this can be done in 2 ways.....
1. Let you Display class implements the ActionListener, then Register the button with
the ActionListener, and finally implement the abstract method actionPerformed() of ActionListener.
Eg:
public class Display extends Canvas implements ActionListener{
public Display(){
// Your code....
setComponent(); // Initializing the state of Components
}
public void setComponent(){
// Your code.........
Button b = new Button("Click");
b.addActionListener(this); // Registering the button.
// Your code..........
}
public void actionPerformed(ActionEvent event) {
// Do here whatever you want on the Button Click
}
}
2. Use Anonymous class.
- Anonymous class are declared and initialized simultaneously.
- Anonymous class must implement or extend to only one interface or class resp.
Your Display class will NOT implement ActionListener here....
public class Display extends Canvas {
public Display(){
// Your code....
setComponent(); // Initializing the state of Components
}
public void setComponent(){
// Your code.........
Button b = new Button("Click");
// Registering the button and Implementing it
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
// Do here whatever you want on the Button Click
}
});
// Your code..........
}
}
You need to implement ActionListner :
public class Display extends Canvas implements ActionListener
and add yourself to your button as such:
erase.addActionListener(this);
and then implement the required method:
public void actionPerformed(ActionEvent event) {
//do stuff
}
For more info, check out this tutorial on creating ActionListeners.
You'll find that this observable pattern is widely used the in Java GUI.
A couple high level critiques:
You are using many older AWT components (ie Button) when there are similar, but newer (read: more flexible) Swing components available (ie JButton). Take a look at this for a quick explanation on the difference.
The event model that you have implemented was revamped in 1997 to the observable pattern that I suggested above. If you would like to learn more, you can read this.

Categories

Resources