I need to create a bank account management program for school, I created the "skeleton" of the first page but I do not understand some things:
How to open a new window with Swing when I click a button?
How can I have different ActionListener for each button?
If I change strategy and I want to use just one big window and let appear and disappear the working text fields/Labels, how would I do it?
Code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
public class CreditUnion extends JFrame
{
//declare buttons
private JButton openAccount;
private JButton closeAccount;
private JButton makeLodgement;
private JButton makeWithdrawal;
private JButton requestOverdraft;
//constructor
public CreditUnion()
{
super("ATM#CreditUnion");
Container c = getContentPane();
c.setLayout(new FlowLayout() );
openAccount = new JButton("Open account");
c. add(openAccount);
closeAccount = new JButton("Close account");
c. add(closeAccount);
makeLodgement = new JButton("Make lodgement");
c. add(makeLodgement);
makeWithdrawal = new JButton("Make withdrawal");
c. add(makeWithdrawal);
requestOverdraft = new JButton("Request overdraft");
c. add(requestOverdraft);
/*create instance of inner class ButtonHandler
to use for button event handling*/
ButtonHandler handler = new ButtonHandler();
openAccount.addActionListener(handler);
closeAccount.addActionListener(handler);
makeLodgement.addActionListener(handler);
makeWithdrawal.addActionListener(handler);
requestOverdraft.addActionListener(handler);
setSize(800,600);
show();
}
public static void main (String args[])
{
CreditUnion app = new CreditUnion();
app.addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
//inner class for button event handling
private class ButtonHandler implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
JOptionPane.showMessageDialog(null, "You Pressed: " + e.getActionCommand() );
}
}
how to open a new window with Swing when I click a button?
Don't, use a CardLayout, it's less distracting to the user
Have a look at How to use CardLayout for more details
how can I have different ActionListener for each button?
You can use a separate class, inner class or anonymous class depending on what you to achieve
Have a look at Nested classes for more details
if I change strategy and I want to use just one big window and let appear and disappear the working Textfields/Labels, how would I do it
See the first point
1- how to open a new window with Swing when I click a button?
The same way that you would display any window. In the button's ActionListener, create a new window -- I would suggest that you create a JDialog and not a JFrame, but this will depend on your assignment requirements too, and display it
2- how can I have different ActionListener for each button?
Add a different ActionListener to each button. An anonymous inner class (search on this) would work great for this.
3- if I change strategy and I want to use just one big window and let appear and disappear the working Textfields/Labels, how would I do it?
Use a CardLayout to swap "views", usually JPanels with components that you want to swap.
Related
I am working on a GUI and trying to get different buttons to perform different tasks.
Currently, each button is leading to the same ActionListener.
public class GUIController {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridLayout(3,3));
JLabel leight =new JLabel("8");
frame.getContentPane().add(leight);
JLabel lfive =new JLabel("0");
frame.getContentPane().add(lfive);
JLabel lthree =new JLabel("0");
frame.getContentPane().add(lthree);
JButton beight =new JButton("Jug 8");
frame.getContentPane().add(beight);
JButton bfive =new JButton("Jug 5");
frame.getContentPane().add(bfive);
JButton bthree =new JButton("Jug 3");
frame.getContentPane().add(bthree);
LISTN ccal = new LISTN (leight,lfive,lthree);
beight.addActionListener(ccal);
bfive.addActionListener(ccal);
bthree.addActionListener(ccal);
frame.pack();
frame.setVisible(true);
}
}
my actionlistener file
public class JugPuzzleGUILISTN implements ActionListener {
JLabel leight;
JLabel lfive;
JLabel lthree;
JugPuzzleGUILISTN(JLabel leight,JLabel lfive, JLabel lthree){
this.leight = leight;
this.lfive = lfive;
this.lthree = lthree;
}
public void actionPerformed(ActionEvent e) {
}
}
}
Anything I write in ActionEvent applies to all three buttons, how can I make it so that each button has their own function?
Thank you so much!
how can I make it so that each button has their own function
Add a different ActionListener to each button.
Better yet, use an Action instead of an ActionListener. An Action is just a fancy ActionListener that has a few more properties.
Read the section from the Swing tutorial on How to Use Action for examples of defining inner classes so you can create a unique Action for each button.
Anything I write in ActionEvent applies to all three buttons, how can I make it so that each button has their own function?
You have similar actions which you want all the 3 buttons to be able to trigger. However you also have different functions which you want to implement for each button.
One of the ways will creating 3 more listeners, each to be added to their respective button. So each button now will be added with 2 listeners (your current one + newly created ones).
//Example:
beight.addActionListener(ccal);
bfive.addActionListener(ccal);
bthree.addActionListener(ccal);
beight.addActionListener(ccal_beight);
bfive.addActionListener(ccal_bfive);
bthree.addActionListener(ccal_bthree);
There are other ways such as using if-statements in your current listener to check which button is clicked, but I find separate listeners easier to maintain with lower code coupling.
This is not a duplicate as I already know the code .setEnabled(false);. My problem is that I am making a gui in netbeans and I cannot figure out how to disable/enable buttons. Obviously I am new to JAVA and Netbeans This is what I have to do:
Start the program with all buttons disabled except the Initialize
button.
When Initialize is pressed the ArrayList will be filled with 5 CD
titles. The Initialize button then becomes disabled and the other
buttons become enabled.
The only code I know for buttons is .setEnabled(false); but it only disables button after I click it and what i need is to make one enabled and rest disabled. After I click it, it should be disabled and rest should be enabled.
The current code is not relevant but if you need it I will edit this post! Any help is greatly appreciated and thank you in advance!
You need to use interface ActionListener and add ActionListener after clicking
of button. Implement default method ActionPerformed. Use this code as example.
import java.awt.*;
import java.awt.event.*;
class calc extends Frame implements ActionListener
{
TextField t1 =new TextField(20);
TextField t2 =new TextField(29);
TextField t3 =new TextField(29);
Label l1=new Label("first");
Label l2=new Label("second");
Label l3=new Label("sum");
Button b1=new Button("Add");
Button b2=new Button("close");
calc() //CONSTRUCTOR
{
add(l1);add(t1);
add(t2);add(l2);
add(t3);add(l3);
add(b1);
add(b2);
setSize(444,555);
setVisible(true);
setLayout(new FlowLayout());
b1.addActionListener(this);
b2.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
Object o=e.getSource();
if(o==b2)
{
System.exit(1);
}
String n1=t1.getText();
String n2=t2.getText();
int a=Integer.parseInt(n1);
int b=Integer.parseInt(n2);
t3.setText(""+(a+b));
}
}
class Gi
{
public static void main(String[] args)
{
new calc();
}
}
I wrote a program for an applet that is supposed to display different text in a text box when you push a button. My program has no errors when I compiled it, but the text box doesn't display correctly. I don't know what is wrong with it. Here is my code
import java.awt.*;
import java.awt.event.*;
public class colors{
Button button1;
Button button2;
Button button3;
Label label1;
TextField objTextField1;
public static void main (String args[]){
colors c = new colors();
}
public colors() {
Frame f = new Frame ("Colors");
Button button1 = new Button("Blue");
button1.setBounds(10,305,120,75);
button1.addMouseListener(new MyMouseListener1());
Button button2 = new Button("Red");
button2.setBounds(140,305,120,75);
button2.addMouseListener(new MyMouseListener2());
Button button3 = new Button("Yellow");
button3.setBounds(270,305,120,75);
button3.addMouseListener(new MyMouseListener3());
f.add(button1);
f.add(button2);
f.add(button3);
label1 = new Label("Click a Button to Reveal Text");
label1.setBounds(20,105,200,25);
f.add(label1);
objTextField1 = new TextField("Which Color?", 15);
objTextField1.setBounds(20,75,125,50);
f.add(objTextField1);
f.add(label1);
f.add(objTextField1);
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
f.setSize(400,400);
f.setVisible(true);
}
public class MyMouseListener1 extends MouseAdapter{
public void mouseClicked(MouseEvent me){
objTextField1.setText("Blue");
}
}
public class MyMouseListener2 extends MouseAdapter{
public void mouseClicked(MouseEvent me){
objTextField1.setText("Red");
}
}
public class MyMouseListener3 extends MouseAdapter{
public void mouseClicked(MouseEvent me){
objTextField1.setText("Yellow");
}
}
}
When a Button is clicked it fires an ActionEvent.
You should use an ActionListener instead of a MouseListener.
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
AND don't forget to add
button.addActionListener(instance);
I have tested your code and it's working as expected but I have noticed some of the points in your code as mentioned below:
Use setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) instead of System.exit(0) and adding WindowListener to close the window.
Use frame.pack() instead of frame.setSize() that fits the components as per component's preferred size.
Don't use null layout and never use absolute positioning via calling setBounds() instead use a proper Layout Manager that suits as per your application design.
Read more How to Use Various Layout Managers
Use SwingUtilities.invokeLater() or EventQueue.invokeLater() to make sure that EDT is initialized properly.
Read more
Why to use SwingUtilities.invokeLater in main method?
SwingUtilities.invokeLater
Should we use EventQueue.invokeLater for any GUI update in a Java desktop application?
Follow Java Naming convention
Keep the instance members private
This is already addressed by #TAsk that you should be using ActionListener instead of MouseListener if you are interested in only mouseClicked() method.
You should be using Swing components instead of AWT components as already mentioned by #peeskillet
To make an applet you should extend javax.swing.JApplet class & override init() method.
To change the color, you must write your logics in actionPerformed() of ActionListener. But it's an interface. So, you can make use of Anonymous Inner class & implement actionPerformed() in it.
So, when you call addActionListener() on a JButton, I recommend you to do that by using Anonymous Inner class. It would be more clear through following code.
My Suggestion: Whenever you write code, always keep OOD principles in your mind. This isn't right place to discuss that, but your code has a Code smell which is Duplication in code.
Below is the best way to do what you want & we're also using DRY Principle.
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class ColorChanger extends javax.swing.JApplet {
private JPanel mainPanel;
private JButton btnRed;
private JButton btnGreen;
private JButton btnBlue;
#Override
public void init() {
super.init();
mainPanel = new JPanel();
btnRed = new JButton("Red");
btnGreen = new JButton("Green");
btnBlue = new JButton("Blue");
this.add(mainPanel);
mainPanel.add(btnRed);
mainPanel.add(btnGreen);
mainPanel.add(btnBlue);
bindActionEvent(btnRed, Color.RED);
bindActionEvent(btnGreen, Color.GREEN);
bindActionEvent(btnBlue, Color.BLUE);
}
private void bindActionEvent(JButton b1, Color color) {
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mainPanel.setBackground(color);
//Write setText() for your TextField here.
}
});
} //END Of Helper Method
}
I have been told by my teacher that having a separate class for the actionListener is best. In the separate class, should I just make one actionListener method eg.
public void actionPerformed(ActionEvent e) {
if(e.getSource() == myButton) {
//do something
}
else if(e.getSource() == myComboBox) {
//do something
}
}
or should I make many? I have a feeling I should make many but I have no idea how to go about it. What would the different parameters be? I will be making an instance of this class in my View class where the button and combobox is. (this would be the Controller class as i'm trying to do MVC)
For the button I would like for the background to change colour when the mouse hovers over it and then of course do something when clicked. The combobox simply needs to return whatever option was selected as String.
I prefer to write a separate action listener for each controller action. It keeps things simpler for my simple mind.
My rule of thumb is, for very short (1 - 3 lines) action listeners, I'll make them inline anonymous classes.
For medium size action listeners (1 - 3 methods), I'll make them an inner class, especially if the action listener needs 3 or more fields from the outer main class.
For large action listeners, I'll write a separate class.
When you make a separate class for the action listener, you can reuse the action event you made.
I will give you an example for that
This class have an action listener
class AListener implements ActionListener
{
JTextField tf;
AListener(JTextField tf)
{
this.tf=tf;
}
public void actionPerformed(ActionEvent e)
{
if((e.getActionCommand()).equals("Button1"))
tf.setText("Button1 clicked");
if((e.getActionCommand()).equals("Button2"))
tf.setText("Button2 clicked");
if((e.getActionCommand()).equals("Button3"))
tf.setText("Button3 clicked");
}
}
And this is the GUI class, which has 3 buttons and one text field and each button print something different in the text field, so as you can see, it is not logical to make 3 different action listener methods in the GUI class.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ActionDemo extends JFrame
{
public ActionDemo()
{
setLayout(new FlowLayout());
// Add buttons to the frame
JButton b1=new JButton("Button1");
JButton b2=new JButton("Button2");
JButton b3=new JButton("Button3");
JTextField tf=new JTextField(10);
AListener listen=new AListener(tf);
b1.addActionListener(listen);
b2.addActionListener(listen);
b3.addActionListener(listen);
add(b1);add(b2);add(b3);add(tf);
}
public static void main(String[] args)
{
ActionDemo frame = new ActionDemo();
frame.setTitle("Action Demo");
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 100);
frame.setVisible(true);
}
}
So now, every time a button clicked, one action listener method only will be called. Inside this method, I will check which button called me.
I am writing a Swing program in which all panels are declared as separate classes and a JFrame that holds the panels. The input panel has a subpanel that has a number of buttons on it. When when one of those buttons is clicked and a value is calculated, I would like to pass that value back to the JFrame holding the input panel, so that the value can be used in a number of other calculations.
I know that I can just use the JFrame ActionListener to be directly responsible for the buttons on the sub panel, but that seems to violate either portability, encapsulation, or both. I want the sub panel to be able to work on its own and let the JFrame using it be aware when a certain value changes.
I would prefer to keep the value as a primitive, but if only an object works, I can go with that.
The program has already been written as one class and it worked fine, but a beast to edit. When I was done, I realized that it was a mistake not to break it down into six panels each as their own class. A lesson for future projects. So, I am rewriting it and running into the problem that the JFrame is dependent on knowing when one of its panels (actually a panel on that panel) recalculates a value. The value calculation isn't a problem, but the JFrame needs to know when it changes.
I hope that is clear. It seemed pretty clear to me! :-)
The following code is a simplification of what I'm trying to do.
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
public class ChangeState extends JFrame {
// This is to receive the value when changed in ButtonPanel
private JTextField answer = new JTextField(5);
private InputPanel inputPanel = new InputPanel();
public ChangeState() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(inputPanel, BorderLayout.CENTER);
add(answer, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public static void main(String[] args) {
ChangeState mf = new ChangeState();
}
}
class InputPanel extends JPanel {
private ButtonPanel buttonPanel = new ButtonPanel();
InputPanel() {
add(buttonPanel);
}
}
class ButtonPanel extends JPanel implements ActionListener {
private int value;
JButton b1 = new JButton("Value *2");
JButton b2 = new JButton("Value *3");
public ButtonPanel() {
value = 1;
b1.addActionListener(this);
add(b1);
b2.addActionListener(this);
add(b2);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
value *= 2;
}
if (e.getSource() == b2) {
value *= 3;
}
System.out.println("Value: " + value);
/*
* How do I let ChangeState.answer know VALUE has changed and needs
* to be updated?
*/
}
}
You can make ChangeState an observer of your ButtonPanel, by being an ActionListener listening to the ButtonPanel, or by being some other custom observer that's more abstract which you can create.
I'd recommend a more abstract custom observer when the class observing is not another GUI class with only one event, but in this case since it is perhaps you can just use an ActionListener (on the other hand, ChangeState is not much of a GUI class, you could have made it be composed of a JFrame).
If you have more than one event that could be passed through that ActionListener, you will probably then need to make ChangeState implement a more abstract observer implementation so you can better distinguish between events. Otherwise you'll need to have ChangeState know the name of some of the different GUI components that created the event's, or have a reference to them which would not be that great design wise.