Okay I can get text fields and normal text and even images to show but I can not get a button to show. I am not sure what I am doing wrong because I have done the same steps for the rest. Any help would be great thanks!
package EventHandling2;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import EventHandling.GUITest;
public class EventMain extends JFrame{
private JLabel label;
private JButton button;
public static void main(String[] args) {
EventMain gui = new EventMain ();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when click x close program
//gui.setSize(600, 300);
gui.setVisible(true);
gui.setTitle("Button Test");
}
public void EventMain(){
setLayout(new FlowLayout());
button = new JButton ("click for text");
add(button);
label = new JLabel ("");
add(label);
Events e = new Events();
button.addActionListener(e);
}
public class Events implements ActionListener {
public void actionPerformed(ActionEvent e) {
label.setText("Now you can see words");
}
}
}
The problem is with the method: void EventMain()
Constructor has NO return type. Just remove "void". The code will work just fine.
Your actionListener(e) contains a minor control structure error:
public void actionPerformed(ActionEvent e) {
label.setText("Now you can see words");
}
Change to:
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
label.setText("Now you can see words");
}
}
First off, you have to remove void keyword in EventMain's constructor. Then, creating JPanel and add components into it, then add the JPanel to the JFrame.contentPane.
The following code should work:
public class EventMain extends JFrame {
private final JLabel label;
private final JButton button;
public static void main(String[] args) {
EventMain gui = new EventMain();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when click x
// close program
gui.setSize(600, 300);
gui.setTitle("Button Test");
gui.setVisible(true);
}
public EventMain() {
// setLayout(new FlowLayout());
JPanel panel = new JPanel(new FlowLayout());
button = new JButton("click for text");
panel.add(button);
label = new JLabel("");
panel.add(label);
Events e = new Events();
button.addActionListener(e);
this.getContentPane().add(panel);
}
public class Events implements ActionListener {
public void actionPerformed(ActionEvent e) {
label.setText("Now you can see words");
}
}
}
Related
ParentFrame shows ArrayList and one "ADD" Button. Once I click "ADD" Button on ParentFrame, then ChildFrame shows up.
On ChildFrame, I type in a String and click "OK" Button then it should transfer its String to ParentFrame. Finally ParentFrame should be repainted with newly added String.
I'm having trouble with repainting but also I might failed to send String from Child to Parent since Parent didn't get repainted.
I tried several things in two or three other points of view but following code seems like to work but......
I need your help!!
ParentFrame
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
#SuppressWarnings("serial")
public class parentFrame extends JFrame {
ArrayList<String> list = new ArrayList<>(){{add("test1"); add("test2");}};
JButton add;
JPanel big, small;
JLabel content;
childFrame addFrame;
public parentFrame() {
super("parent frame");
super.setLayout(new BorderLayout());
super.setSize(600,600);
big = new JPanel();
for(int i=0; i<list.size(); i++) {
content = new JLabel();
content.setText(list.get(i));
big.add(content);
}
super.add(big, BorderLayout.CENTER);
add = new JButton("ADD");
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
addFrame = new childFrame();
/* By next 3 lines, I'm trying to transfer the value of childFrame's test to this parentFrame's list. */
list.add(addFrame.getTestString());
big.revalidate();
big.repaint();
}
});
super.add(add, BorderLayout.SOUTH);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new parentFrame();
}
}
2.ChildFrame
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
#SuppressWarnings("serial")
public class childFrame extends JFrame {
String test;
JTextField name;
JButton ok, cancel;
public childFrame() {
super("child frame");
super.setLayout(new BorderLayout());
super.setSize(400,200);
JPanel centerPanel = new JPanel(new GridLayout(1,1));
centerPanel.setSize(150, 100);
name = new JTextField();
centerPanel.add(name);
JPanel bottomPanel = new JPanel(new FlowLayout());
ok = new JButton("OK");
ok.addActionListener(new OKListener());
super.add(ok);
cancel = new JButton("CANCEL");
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
bottomPanel.add(cancel);
bottomPanel.add(ok);
super.add(centerPanel, BorderLayout.CENTER);
super.add(bottomPanel, BorderLayout.SOUTH);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class OKListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
test = name.getText();
dispose();
}
}
public String getTestString() {
return test;
}
}
Your problem is here:
public void actionPerformed(ActionEvent e) {
addFrame = new childFrame();
list.add(addFrame.getTestString());
big.revalidate();
big.repaint();
}
Since your child frame is not a modal window (for example, a JOptionPane is a modal dialog window), it does not halt program flow in the calling window. You call .getTestString() immediately on creation of the child frame but before the user has had any chance to enter in any data (again, because program flow in the calling window is not halted).
The solution is to make your child "frame" in fact a modal JDialog. This will pretty much solve the whole issue. So, don't have the child frame extend from JFrame, but rather extend JDialog, and use the JDialog constructor that makes it modal (see the JDialog API).
e.g.,
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
#SuppressWarnings("serial")
// note that class names should begin with an upper-case letter
public class ChildFrame extends JDialog {
String test;
JTextField name;
JButton ok, cancel;
public ChildFrame(JFrame parentFrame) {
// the true parameter makes this modal
super(parentFrame, "child frame", true);
Now this dialog window will freeze program flow from the calling code as soon as the dialog is set visible, and the calling code flow won't resume until this dialog is no longer visible.
Also, please have a look at The Use of Multiple JFrames, Good/Bad Practice?
An alternative to this is to continue to use multiple JFrames (not recommended!!), and add a WindowListener to the "child" window, listening for windows closing events, and then getting the information from your dialog in call-back method that is activated when the windows closing event occurs.
For a working example:
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class ParentGuiPanel extends JPanel {
private DefaultListModel<String> listModel = new DefaultListModel<>();
private JList<String> jList = new JList<>(listModel);
private JButton addButton = new JButton("Add");
private JDialog childDialog;
private ChildGuiPanel childPanel = new ChildGuiPanel();
public ParentGuiPanel() {
listModel.addElement("Test 1");
listModel.addElement("Test 2");
jList.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
jList.setVisibleRowCount(8);
JScrollPane scrollPane = new JScrollPane(jList);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
addButton.addActionListener(e -> addActionPerformed(e));
addButton.setMnemonic(KeyEvent.VK_A);
JPanel buttonPanel = new JPanel();
buttonPanel.add(addButton);
setLayout(new BorderLayout());
add(scrollPane);
add(buttonPanel, BorderLayout.PAGE_END);
}
private void addActionPerformed(ActionEvent e) {
Window window = null;
if (childDialog == null) {
window = SwingUtilities.getWindowAncestor(this);
if (window == null) {
return;
}
childDialog = new JDialog(window, "Child GUI", ModalityType.APPLICATION_MODAL);
childDialog.add(childPanel);
childDialog.pack();
childDialog.setLocationRelativeTo(window);
}
if (childDialog != null) {
childDialog.setVisible(true);
String text = childPanel.getText();
if (!text.trim().isEmpty()) {
listModel.addElement(text);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame mainGui = new JFrame("Main GUI");
mainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ParentGuiPanel mainPanel = new ParentGuiPanel();
mainGui.add(mainPanel);
mainGui.pack();
mainGui.setLocationRelativeTo(null);
mainGui.setVisible(true);
});
}
}
#SuppressWarnings("serial")
class ChildGuiPanel extends JPanel {
private JTextField textField = new JTextField(15);
private JButton okButton = new JButton("OK");
private JButton cancelButton = new JButton("Cancel");
public ChildGuiPanel() {
okButton.addActionListener(e -> okActionPerformed(e));
cancelButton.addActionListener(e -> cancelActionPerformed(e));
textField.addActionListener(e -> okActionPerformed(e));
okButton.setMnemonic(KeyEvent.VK_O);
cancelButton.setMnemonic(KeyEvent.VK_C);
add(new JLabel("Text: "));
add(textField);
add(okButton);
add(cancelButton);
}
public String getText() {
return textField.getText();
}
private void disposeWindow() {
textField.selectAll();
Window window = SwingUtilities.getWindowAncestor(this);
if (window != null) {
window.dispose();
}
}
private void okActionPerformed(ActionEvent e) {
disposeWindow();
}
private void cancelActionPerformed(ActionEvent e) {
textField.setText("");
disposeWindow();
}
}
I am trying to have the number the user inputs into the frame either multiply by 2 or divide by 3 depending on which button they decide to click. I am having an hard time with working out the logic to do this. I know this needs to take place in the actionperformed method.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Quiz4 extends JFrame ActionListener
{
// Global Variable Declarations
// Our list input fields
private JLabel valueLabel = new JLabel("Enter a value between 1 and 20: ");
private JTextField valueField = new JTextField(25);
// create action buttons
private JButton multiButton = new JButton("x2");
private JButton divideButton = new JButton("/3");
private JScrollPane displayScrollPane;
private JTextArea display = new JTextArea(10,5);
// input number
private BufferedReader infirst;
// output number
private NumberWriter outNum;
public Quiz4()
{
//super("List Difference Tool");
getContentPane().setLayout( new BorderLayout() );
// create our input panel
JPanel inputPanel = new JPanel(new GridLayout(1,1));
inputPanel.add(valueLabel);
inputPanel.add(valueField);
getContentPane().add(inputPanel,"Center");
// create and populate our diffPanel
JPanel diffPanel = new JPanel(new GridLayout(1,2,1,1));
diffPanel.add(multiButton);
diffPanel.add(divideButton);
getContentPane().add(diffPanel, "South");
//diffButton.addActionListener(this);
} // Quiz4()
public void actionPerformed(ActionEvent ae)
{
} // actionPerformed()
public static void main(String args[])
{
Quiz4 f = new Quiz4();
f.setSize(1200, 200);
f.setVisible(true);
f.addWindowListener(new WindowAdapter()
{ // Quit the application
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
} // main()
} // end of class
Here's something simpler, but it essentially does what you want out of your program. I added an ActionListener to each of the buttons to handle what I want, which was to respond to what was typed into the textbox. I just attach the ActionListener to the button, and then in the actionPerformed method, I define what I want to happen.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Quizx extends JFrame {
private JPanel panel;
private JTextField textfield;
private JLabel ansLabel;
public Quizx() {
panel = new JPanel(new FlowLayout());
this.getContentPane().add(panel);
addLabel();
addTextField();
addButtons();
addAnswerLabel();
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setTitle("Quiz 4");
this.setSize(220, 150);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setVisible(true);
}
private void addTextField() {
textfield = new JTextField();
textfield.setColumns(9);
panel.add(textfield);
}
private void addButtons() {
JButton multButton = new JButton("x2");
JButton divButton = new JButton("/3");
panel.add(multButton);
panel.add(divButton);
addMultListener(multButton);
addDivListener(divButton);
}
private void addLabel() {
JLabel valueLabel = new JLabel("Enter a value between 1 and 20: ");
panel.add(valueLabel);
}
private void addAnswerLabel() {
ansLabel = new JLabel();
panel.add(ansLabel);
}
private void addMultListener(JButton button) {
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
ansLabel.setText(String.valueOf(Integer.parseInt(textfield.getText().trim()) * 2));
}
});
}
private void addDivListener(JButton button) {
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
ansLabel.setText(String.valueOf(Double.parseDouble(textfield.getText().trim()) /3));
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Quizx();
}
});
}
}
Hope that helps.
I am supposed to implement an application to the user that has 2 buttons(Increment/decrement) and a label. When increment is pressed the number increases and decreases by one when decrement is pressed. The number starts at 50. I have it to where it shows the buttons and they work, but they work on 2 different variables, so their is 2 number printed to the screen instead of 1. My question is how can i make the button act on only one number. I have seen people use push etc. but is there another way to do this by passing in a value to both or something? Thanks
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ButtonModifier
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
FlowLayout flow = new FlowLayout();
frame.getContentPane().setLayout(flow);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,300);
frame.setTitle("Button Modifier");
IncrementPanel panel = new IncrementPanel();
DecrementPanel panel1 = new DecrementPanel();
frame.add(panel);
frame.add(panel1);
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DecrementPanel extends JPanel
{
private JButton button1;
private JLabel label;
private int number = 50;
public DecrementPanel()
{
button1 = new JButton("Decrement");
button1.addActionListener(new /*DecrementPanel.*/ButtonListener());
label = new JLabel("" + number);
this.add(button1);
this.add(label);
}
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//int increment = 50;
number--;
label.setText("" + number);
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class IncrementPanel extends JPanel
{
private JButton button;
private JLabel label;
int number = 50;
public IncrementPanel()
{
button = new JButton("Increment");
button.addActionListener(new ButtonListener());
label = new JLabel("" + number);
this.add(button);
this.add(label);
}
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//int increment = 50;
number++;
label.setText("" + number);
}
}
}
I am supposed to implement an application to the user that has 2 buttons(Increment/decrement) and a label."
Then why do you have two?
IncrementPanel panel = new IncrementPanel();
DecrementPanel panel1 = new DecrementPanel();
Just use one and change the text on that one
Should be more like this
public class ButtonModifier extends JFrame {
private JLabel numberLabel = new JLable("50");
private JButton decrease = new JButton("-1");
private JButton increase = new JButton("+1");
private static int num = 50;
public ButtonModifier(){
setLayout(new GridLayout(1, 3));
add(increase);
add(numberLabel);
add(decrease);
increase.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
num++;
numLabel.setText("" + num);
}
});
decrease.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
num--;
numLabel.setText("" + num);
}
});
}
public static void main(String[] args){
JFrame frame = ButtonModifier();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,300);
frame.setTitle("Button Modifier");
frame.setVisible(true);
}
}
You should have one JLabel which will display the only number in your program.
Then your two buttons will do operations on that number and update the label.
Your mistake is that each Panel has its own number and its own Label to display the number.
public class ButtonModifier {
private static int number = 50;
private static JLabel label;
public static void main(String[] args) {
JFrame frame = new JFrame();
label = new JLabel("" + number);
// <SNIP>
JButton increment = new JButton("Increment");
increment.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
number++;
label.setText("" + number);
}
}
JButton decrement = new JButton("Increment");
increment.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
number--;
label.setText("" + number);
}
}
frame.add(label);
frame.add(increment);
frame.add(decrement);
frame.setVisible(true);
}
}
An important note: Swing is not thread-safe, and all the operations with GUI components must be performed on Event Dispatch Thread. So your main must actually look this way:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Here you create the frame and all the components
}
});
}
Take a look at this program :
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class IncDecApp extends JFrame {
private JButton incBtn = new JButton("Increment");
private JButton decBtn = new JButton("Decrement");
private JPanel lowPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
private JLabel showLbl = new JLabel("00", JLabel.CENTER);
private Font myFont = new Font("Tahoma", Font.BOLD, 60);
private int valueInt;
public IncDecApp() {
setTitle("IncDec Application =)");
setDefaultCloseOperation(EXIT_ON_CLOSE);
lowPanel.add(incBtn);
lowPanel.add(decBtn);
incBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
valueInt = Integer.parseInt(showLbl.getText());
valueInt++;
if (valueInt >= 10) {
showLbl.setText(String.valueOf(valueInt));
} else {
showLbl.setText("0" + String.valueOf(valueInt));
}
}
});
decBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
valueInt = Integer.parseInt(showLbl.getText());
if (valueInt > 0) {
valueInt--;
}
if (valueInt >= 10) {
showLbl.setText(String.valueOf(valueInt));
} else {
showLbl.setText("0" + String.valueOf(valueInt));
}
}
});
showLbl.setFont(myFont);
add(showLbl, BorderLayout.CENTER);
add(lowPanel, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new IncDecApp();
}
}
Create the JLabel in the main function. Have the incrementPanel and DecrementPanel classes constructors take a JLabel as an argument that they store as a private variable. The ButtonListeners csn also be passed the JLabel as an argument. Now the button listeners csn update a common JLabel.
Now, you can improve things by combining the code of IncrementPanel and DecrementPanel classes by passing an int in the constructor indicating the increment of +1 or -1.
A quick and dirty way to implement the functionality is through the use of anonymous classes implementing button listeners within a single monolithic class.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class ButtonApplet extends Applet implements ActionListener{
Button buttonInc, buttonDec;
int x=0;
public void init(){
buttonInc=new Button("Increment");
buttonDec=new Button("Decrement");
buttonInc.addActionListener(this);
buttonDec.addActionListener(this);
add(buttonInc);
add(buttonDec);
}
public void paint(Graphics g){
g.drawString("Count is : "+x,50,100);
}
public void actionPerformed(ActionEvent ev){
if(ev.getSource() == buttonInc)
{
x++;
repaint();
}
else if(ev.getSource() == buttonDec){
x--;
repaint();
}
}
}
Make Java GUI Application using AWT
You are required to make one label (Count), one textfield, one button (Increment), one button (Decrement) and one button (Close)
When the increment button is clicked, you need to increment the value in textfield, value should be incremented again and again when the button is clicked
When the decrement button is clicked, you need to decrement the value in textfield, value should be decremented again and again when the button is clicked
When the close button is clicked, you need to close the AWT Frame
I have the following code which creates a simple window with two buttons which are in turn suppose to open up a window each - the main window opens up just fine but when you click on the buttons nothing happens...
package presentation;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ShowInventory extends JFrame {
/**
*
*/
private static final long serialVersionUID = 7479750059244371227L;
private JPanel contentPane;
private JButton catBtn = new JButton ("Display inventory by category");
private JButton allBtn = new JButton ("Display all inventory");
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ShowInventory frame = new ShowInventory();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Exception - Sorry");
}
}
});
}
/**
* Default - details to be added
*/
public ShowInventory() { // title bar name
// layout here
Container container = getContentPane();
FlowLayout layout = new FlowLayout();
container.setLayout(layout);
layout.setAlignment(FlowLayout.CENTER);
container.add(new JButton("Display inventory by category"));
container.add(new JButton("Display all inventory"));
catBtn.addActionListener (new ActionListener() {
public void actionPerformed (ActionEvent event) {
// controller code
ShowByCategory frame = new ShowByCategory();
frame.setVisible(true);
}
});
allBtn.addActionListener (new ActionListener() {
public void actionPerformed (ActionEvent event) {
// controller code
ShowAllInventory frame = new ShowAllInventory();
frame.setVisible(true);
}
});
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
You probably need to replace those lines (which create brand new buttons):
container.add(new JButton("Display inventory by category"));
container.add(new JButton("Display all inventory"));
by this (which uses the buttons of your class, on which you then add the listeners):
container.add(catBtn);
container.add(allBtn);
What am I missing here?
public class abc extends JFrame {
private JButton save = new JButton("Save");
public abc() {
JPanel p = new JPanel();
save.addActionListener(new SaveL());
p.add(save);
Container cp = getContentPane();
p = new JPanel();
p.setLayout(new GridLayout(2, 1));
cp.add(p, BorderLayout.NORTH);
}
}
class SaveL implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Hello"); // nothing happens
}
}
Why doesn't my ActionListener work here
You are creating a JPanel, adding your JButton to it, then creating a new JPanel and adding that panel to your JFrame. You need to be adding the original panel to your content pane.
Your code is completely messed up. You instantiate your JPanel p twice, your button is declared "open" but is actually "save". You mix GridLayout with BorderLayour constraints. The following code works:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class abc extends JFrame {
private JButton save = new JButton("Save");
public abc() {
JPanel p = new JPanel();
save.addActionListener(new SaveL());
p.add(save);
p.setLayout(new GridLayout(2, 1));
add(p);
}
public static void main(String[] args) {
abc abc = new abc();
abc.pack();
abc.setVisible(true);
}
}
class SaveL implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Hello"); // nothing happens
}
}
Your code is re-creating the panel. It's losing the button.
I changed it to:
public class abc extends JFrame{
private JButton save = new JButton("Save");
public abc() {
JPanel p = new JPanel();
save.addActionListener(new SaveL());
p.add(save);
Container cp = getContentPane();
cp.add(p, BorderLayout.NORTH);
}
}
class SaveL implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Hello"); // nothing happens
}
}
and it worked
private JButton open = new JButton("Save");
save.addActionListener(new SaveL());
Did u declare your save as open?