I'm not sure how to write this line of code correctly, but what I'm trying to get is, " if the count of the e.getSource is 1, set it to 0".
Would that be written as:
if (count.(e.getSource()) == 1)
{
count = 0;
}
What would be the correct way of writing count.(e.getSource()) ?
e.getSource returns the object on which the Event initially occurred. You can get the JButton which triggers the event by casting it:
((JButton)e.getSource())
However, the button itself will not keep track of the number of times it has been clicked. You can just declare a variable to keep track of the clicks.
class DrawingSpace extends JPanel
{
private JButton btn;
private int count;
public DrawingSpace(){
count = 0;
btn = new JButton("Click me");
btn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
if (count == 1)
count = 0;
}
});
}
}
To illustrate the point where you do not need a variable name to access the instance of the button being clicked. Take a look at this working example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class CountClicks{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
JFrame frame = new JFrame("Counting individual clicks");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawingSpace());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Your customized Button class:
class MyButton extends JButton
{
private int numOfClicks; //Add additional property for JButton
public MyButton(String name){
super(name);
numOfClicks = 0;
}
public int getClicks(){
return numOfClicks;
}
public void setClicks(int clicks){
this.numOfClicks = clicks;
}
}
A container to contain your components for testing:
class DrawingSpace extends JPanel
{
private MyButton[] btn;
private JLabel lblDisplay;
public DrawingSpace(){
setPreferredSize(new Dimension(450, 100));
init();
}
private void init(){
btn = new MyButton[5];
ButtonHandler bh = new ButtonHandler();
for(int x=0; x<btn.length; x++){
btn[x] = new MyButton("Button " + (x+1));
btn[x].addActionListener(bh);
add(btn[x]);
}
lblDisplay = new JLabel("Watch here..");
add(lblDisplay);
}
private class ButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
MyButton myBtn = (MyButton)e.getSource();
myBtn.setClicks(myBtn.getClicks()+ 1);
lblDisplay.setText(myBtn.getText() + " was clicked, it has gathered " + myBtn.getClicks() + " so far.");
}
}
}
An alternative solution if you want each Button to remembers how many times it has been clicked, you may create a customized JButton:
class MyButton extends JButton
{
private int numOfClicks; //Add additional property for JButton
public MyButton(String name){
super(name);
numOfClicks = 0;
}
public int getClicks(){
return numOfClicks;
}
public void setClicks(int clicks){
this.numOfClicks = clicks;
}
}
Now each of your customized buttons can remember the number of times each of them is being clicked:
class DrawingSpace extends JPanel
{
private MyButton btn;
public DrawingSpace(){
btn = new MyButton("Click me");
btn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
MyButton myBtn = (MyButton)e.getSource();
if (myBtn.getClicks() == 1)
myBtn.setClicks(0);
}
});
}
}
Related
introduceButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) {
int agex = Integer.parseInt(datafield.getText());
String box[] = {"paws quantity", "tail(cm)","paws qy"};
ArrayList<Integer> objdata = new ArrayList<Integer>();
for(int z = 0; z < 3;){
introduceButton
txtvar.setText(box[z]);
if (introduceButton.getModel().isEnabled() == true){
z++;
}
}
}
});
Hey guys, I try to count step by step how many times the button was pressed, to later navigate in an array.
The problem is that the variable z is not incrementing itself only by 1 after the button was clicked once but it reaches its max instantly after the first click. How can I fix it?
As well I tried to make a class with method counter but it the value remains 0:
class click{
int _incr;
public click(int incr){
_incr = incr;
}
public int count(){
_incr++;
return _incr;
}
}
...
introduceButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) {
int agex = Integer.parseInt(datafield.getText());
String box[] = {"paws quantity", "tail(cm)","paws qy"};
ArrayList<Integer> objdata = new ArrayList<Integer>();
click clck = new click(0);
txtvar.setText(Integer.toString(clck._incr));
/*for(int z = 0; z < 3;){
txtvar.setText(box[z]);
if(introduceButton.getModel().isEnabled() == true){
z++;
}
}*/
objdata.add(agex);
dog abstractdog = new dog(agex, agex, agex);
}
});
I made a example code.
Please have a look at it:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CountClick {
static int clicks = 0;
public static void main(String[] args) {
Frame f = new Frame("Button Example");
Button btn = new Button("Click me");
btn.setBounds(50, 100, 80, 30);
f.add(btn);
// set size, layout and visibility of frame
f.setSize(400, 400);
f.setLayout(null);
f.setVisible(true);
// add listener
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// increase click int
clicks++;
// print clicks
System.out.println(clicks);
}
});
}
}
Note that the code in "addActionListener" is triggered each time you press the button. Therefore, unnecessary operations in it should be avoided. Initialisations should also be used with care in the "addActionListener" method.
Edit:
If you want to have a separate click class you can have a look at following code example:
class Click {
private int click = 0;
public void increaseClick() {
click++;
}
public int getClick() {
return click;
}
}
public class CountClicks {
public static void main(String[] args) {
Frame f = new Frame("Button Example");
Button btn = new Button("Click me");
btn.setBounds(50, 100, 80, 30);
f.add(btn);
// set size, layout and visibility of frame
f.setSize(400, 400);
f.setLayout(null);
f.setVisible(true);
Click click = new Click();
// add listener
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// increase click int
click.increaseClick();
// print clicks
System.out.println(click.getClick());
}
});
}
}
So for school, we have to make 2 separate JFrames that interact with each other. From within the first JFrame, a button gets pressed which opens the second one, where a name, speed, and position can be filled in.
When pressing OK on the second JFrame, I save the filled-in text and numbers but I have no clue how to use them in the code of the first JFrame. I had tried to use a "getter" from the second JFrame to check in the first one if the "OK" button had been pressed. But this gets checked immediately after opening the window. That means it isn't true YET and it doesn't check it again.
CONTEXT:
We are forced to use 2 separate JFrame.
We are not allowed to add extra methods.
We are not allowed to change the constructor.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TourFrame extends JFrame implements ActionListener{
private Etappe etappe;
private JLabel jlAantal;
private JTextField jtfAantal;
private JButton knopPrint;
private JButton knopStap;
private JButton knopVoegFietsenToe;
private JButton knopVoegCustomFietsToe;
public TourFrame(Etappe etappe){
this.etappe = etappe;
setTitle("Tour de Windesheim: " + etappe.toString());
setSize(650, 550);
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jlAantal = new JLabel("aantal:");
add(jlAantal);
jtfAantal = new JTextField(10);
add(jtfAantal);
knopPrint = new JButton("print");
add(knopPrint);
knopPrint.addActionListener(this);
knopStap = new JButton("stap");
add(knopStap);
knopStap.addActionListener(this);
knopVoegFietsenToe = new JButton("voeg fietsen toe");
add(knopVoegFietsenToe);
knopVoegFietsenToe.addActionListener(this);
knopVoegCustomFietsToe = new JButton("voeg custom fiets toe");
add(knopVoegCustomFietsToe);
knopVoegCustomFietsToe.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == knopPrint){
etappe.print();
} else if(e.getSource() == knopStap){
etappe.stap();
setTitle("Tour de Windesheim: " + etappe.toString());
} else if(e.getSource() == knopVoegFietsenToe){
try {
int aantal = Integer.parseInt(jtfAantal.getText());
for(int i = 0; aantal > i; i++){
Fiets tijdelijk = new Fiets();
etappe.voegDeelnemerToe(tijdelijk);
}
} catch (NumberFormatException nfe){
jlAantal.setText("Voer een getal in");
}
} else if(e.getSource() == knopVoegCustomFietsToe){
FietsDialoog fietsdialoog = new FietsDialoog();
}
}
}
The Second one looks as follwed:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FietsDialoog extends JFrame implements ActionListener {
private JLabel jlNaam;
private JTextField jtfNaam;
private JLabel jlStartPositie;
private JTextField jtfStartPositie;
private JLabel jlSnelheid;
private JTextField jtfSnelheid;
private JButton knopOk;
private JButton knopCancel;
private String naam;
private int startpositie;
private int snelheid;
private boolean ok;
private boolean cancel;
public FietsDialoog(){
setTitle("FietsDialoog");
setSize(600, 100);
setLayout(new FlowLayout());
setDefaultCloseOperation(HIDE_ON_CLOSE);
jlNaam = new JLabel("naam");
add(jlNaam);
jtfNaam = new JTextField(10);
add(jtfNaam);
jlStartPositie = new JLabel("startpositie");
add(jlStartPositie);
jtfStartPositie = new JTextField(10);
add(jtfStartPositie);
jlSnelheid = new JLabel("snelheid");
add(jlSnelheid);
jtfSnelheid = new JTextField(10);
add(jtfSnelheid);
knopOk = new JButton("ok");
add(knopOk);
knopOk.addActionListener(this);
knopCancel = new JButton("cancel");
add(knopCancel);
knopCancel.addActionListener(this);
setVisible(true);
}
public String getNaam() {
return naam;
}
public int getStartpositie() {
return startpositie;
}
public int getSnelheid() {
return snelheid;
}
public boolean isOk() {
return ok;
}
public boolean isCancel() {
return cancel;
}
public JButton getKnopOk() {
return knopOk;
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == knopOk){
this.naam = jtfNaam.getText();
this.startpositie = Integer.parseInt(jtfStartPositie.getText());
this.snelheid = Integer.parseInt(jtfSnelheid.getText());
this.ok = true;
this.cancel = false;
} else if(e.getSource() == knopCancel){
this.ok = false;
this.cancel = true;
dispose();
}
}
}
Try and print fietsdialoog.getNaam(), fietsdialoog.getStartpositie()...etc, the getter from the fietsdialoog class after closing the window.
Also, rather than dispose the window: use setVisible to false. JFrame.setVisible(true/false);
I am creating a simple calculator for a school assignment but I can't get it to work for multiple digits
package calculator;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Container;
public class Calculator implements ActionListener{
JFrame guiFrame;
JPanel buttonPanel;
JTextField numberCalc;
int calcOperation = 0;
int currentCalc;
public static void main(String[] args) {
//Use the event dispatch thread for Swing components
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new Calculator();
}
});
}
public Calculator()
{
guiFrame = new JFrame();
//make sure the program exits when the frame closes
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Simple Calculator");
guiFrame.setSize(300,300);
//This will center the JFrame in the middle of the screen
guiFrame.setLocationRelativeTo(null);
numberCalc = new JTextField();
numberCalc.setHorizontalAlignment(JTextField.RIGHT);
numberCalc.setEditable(false);
guiFrame.add(numberCalc, BorderLayout.NORTH);
buttonPanel = new JPanel();
//Make a Grid that has three rows and four columns
buttonPanel.setLayout(new GridLayout(4,4));
guiFrame.add(buttonPanel, BorderLayout.CENTER);
//Add the number buttons
for (int i=1;i<10;i++)
{
addButton(buttonPanel, String.valueOf(i));
}
JButton addButton = new JButton("+");
addButton.setActionCommand("+");
OperatorAction subAction = new OperatorAction(1);
addButton.addActionListener(subAction);
JButton subButton = new JButton("-");
subButton.setActionCommand("-");
OperatorAction addAction = new OperatorAction(2);
subButton.addActionListener(addAction);
JButton multiplyButton = new JButton("*");
multiplyButton.setActionCommand("*");
OperatorAction multiAction = new OperatorAction(3);
multiplyButton.addActionListener(multiAction);
JButton divideButton = new JButton("/");
divideButton.setActionCommand("/");
OperatorAction diviAction = new OperatorAction(4);
divideButton.addActionListener(diviAction);
JButton clearButton = new JButton("ce");
clearButton.setActionCommand("ce");
OperatorAction clearAction = new OperatorAction(5);
clearButton.addActionListener(clearAction);
JButton blankButton = new JButton(" ");
JButton equalsButton = new JButton("=");
equalsButton.setActionCommand("=");
equalsButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
if (!numberCalc.getText().isEmpty())
{
int number = Integer.parseInt(numberCalc.getText());
if (calcOperation == 1)
{
int calculate = currentCalc + number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 2)
{
int calculate = currentCalc - number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 3)
{
int calculate = currentCalc * number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 4)
{
int calculate = currentCalc / number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 5)
{
int calculate = 0;
numberCalc.setText(Integer.toString(calculate));
}
}
}
});
buttonPanel.add(addButton);
buttonPanel.add(subButton);
buttonPanel.add(equalsButton);
buttonPanel.add(divideButton);
buttonPanel.add(multiplyButton);
buttonPanel.add(clearButton);
buttonPanel.add(blankButton);
guiFrame.setVisible(true);
}
//All the buttons are following the same pattern
//so create them all in one place.
private void addButton(Container parent, String name)
{
JButton but = new JButton(name);
but.setActionCommand(name);
but.addActionListener(this);
parent.add(but);
}
//As all the buttons are doing the same thing it's
//easier to make the class implement the ActionListener
//interface and control the button clicks from one place
#Override
public void actionPerformed(ActionEvent event)
{
//get the Action Command text from the button
String action = event.getActionCommand();
//set the text using the Action Command text
numberCalc.setText(action);
}
private class OperatorAction implements ActionListener
{
private int operator;
public OperatorAction(int operation)
{
operator = operation;
}
public void actionPerformed(ActionEvent event)
{
currentCalc = Integer.parseInt(numberCalc.getText());
calcOperation = operator;
}
}
}
However when I run the code It will not allow me to enter in numbers with more than one digit. Also the ce button I created will not reset to zero.
I have included an image of the output.
Thanks in advance.
Output of calculator
The ActionListener is not correct
#Override
public void actionPerformed(ActionEvent event)
{
//get the Action Command text from the button
String action = event.getActionCommand();
//set the text using the Action Command text
numberCalc.setText(action);
}
This will set the numberCalc text to the value of the button, not append the value.
Use numberCalc.setText(NumberCalc.getText() + action); to append the text
Also, for OperatorAction, you don't update any GUI component
public void actionPerformed(ActionEvent event)
{
currentCalc = Integer.parseInt(numberCalc.getText());
calcOperation = operator;
}
You should clear numberCalc to wait for the next value or you will end up with 1 + 12 instead of 1 + 2.
If the button is clearButton, you need to change the logic and reset everything currentCalc, numberCalc, calcOperation, ...
I'm fairly new to Java and could do with some help. I trying to make a Timer countdown from a set time to 0. I have this functionality working fine, but I want to add functionality to allow me to stop the Timer as it's counting down.
Here is my code (I'm trying to achieve this using MVC)
This is the control part:
import java.awt.event.*;
import javax.swing.*;
public class StartButton extends JButton implements ActionListener
{
private TimerModel model;
private Timer timer;
private boolean isStarted;
public StartButton(String buttonText, TimerModel model)
{
super(buttonText);
addActionListener(this);
this.model = model;
isStarted = false;
}
public void actionPerformed(ActionEvent evt)
{
if(!isStarted)
{
timer = new Timer(1000, this);
timer.start();
isStarted = true;
}
model.timerCountdown();
}
public void stopTimer()
{
timer.stop();
}
}
I have looked at some other similar issues online and I tried this within the constructor (Note: I didn't use implements ActionListener, and removed the actionPerformed method I had above):
if(buttonText.equals("Start"))
{
addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(!isStarted)
{
timer = new Timer(1000, this);
timer.start();
isStarted = true;
}
model.timerCountdown();
}
});
}
if(buttonText.equals("Stop"))
{
addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
timer.stop();
}
});
}
Now this part handles the counting down ok, but when I click the stop button it shows an exception(See stack trace here), and it continues to count down.
I have limited knowledge, but I guess it's something to do with the way I'm trying to stop the Timer.
I would appreciate it if someone could point me in the right direction, or at least explain to me why this happens.
Again, if you're not changing the basic behavior of the JButton itself, such as how it is drawn, but instead are only changing the button's title and behavior when pressed, then don't extend JButton. Instead give each button its own Action, an object from a class that extends from AbstractAction. Consider these guys as similar to ActionListeners on steroids. They have the same abilities as ActionListeners and then some since they can easily change the button's title, whether it is enabled or not, its mnemonic, icon,...
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyTimerGui {
private static final String TITLE = "Flashing Label";
private static final int TIMER_DELAY = 200;
private static final int GAP = 3;
private static final float LABEL_POINTS = 32F;
private JPanel mainPanel = new JPanel();
private JLabel flashyLabel = new JLabel(TITLE, SwingConstants.CENTER);
private Timer timer = new Timer(TIMER_DELAY, new TimerListener());
public MyTimerGui() {
Font font = flashyLabel.getFont();
font = font.deriveFont(LABEL_POINTS);
flashyLabel.setFont(font);
flashyLabel.setOpaque(true);
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, 0));
buttonPanel.add(new JButton(new StartAction(this, "Start", KeyEvent.VK_S)));
buttonPanel.add(new JButton(new StopAction(this, "Stop", KeyEvent.VK_T)));
buttonPanel.add(new JButton(new ExitAction(this, "Exit", KeyEvent.VK_X)));
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.setLayout(new BorderLayout());
mainPanel.add(flashyLabel, BorderLayout.CENTER);
mainPanel.add(buttonPanel, BorderLayout.PAGE_END);
}
public JComponent getMainComponent() {
return mainPanel;
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
flashyLabel.setForeground(null);
flashyLabel.setBackground(null);
}
public void exit() {
timer.stop();
Window win = SwingUtilities.getWindowAncestor(mainPanel);
win.dispose();
}
private class TimerListener implements ActionListener {
private final Color foreground1 = Color.green;
private final Color background1 = Color.red;
#Override
public void actionPerformed(ActionEvent aEvt) {
Color fg = flashyLabel.getForeground();
if (foreground1.equals(fg)) {
flashyLabel.setForeground(null);
flashyLabel.setBackground(null);
} else {
flashyLabel.setForeground(foreground1);
flashyLabel.setBackground(background1);
}
}
}
private class StartAction extends AbstractAction {
private MyTimerGui myTimerGui;
public StartAction(MyTimerGui myTimerGui, String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myTimerGui = myTimerGui;
}
#Override
public void actionPerformed(ActionEvent e) {
myTimerGui.start();
}
}
private class StopAction extends AbstractAction {
private MyTimerGui myTimerGui;
public StopAction(MyTimerGui myTimerGui, String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myTimerGui = myTimerGui;
}
#Override
public void actionPerformed(ActionEvent e) {
myTimerGui.stop();
}
}
private class ExitAction extends AbstractAction {
private MyTimerGui myTimerGui;
public ExitAction(MyTimerGui myTimerGui, String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myTimerGui = myTimerGui;
}
#Override
public void actionPerformed(ActionEvent e) {
myTimerGui.exit();
}
}
private static void createAndShowGui() {
MyTimerGui myTimerGui = new MyTimerGui();
JFrame frame = new JFrame("MyTimer");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(myTimerGui.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I agree with the comments that say you shouldn't be extending a JButton. Maybe the logic should be carried out in the main class of your application, the same class that class that deals with the creation and storage of the components.
But I digress. To answer your question, I think there are really two ways to approach this. Either (A) have the actionListener stored within your class as you did in your code or (B) write an actionListener outside of the object itself.
Was the constructor you tried to implement this in the main class constructor?
I think you need something like the following (this, again, is in the main class):
StartButton start = new JButton("Start");
StopButton stop = new JButton("Stop");
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// called when the button is pressed
buttonPressed();
}
});
stop.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// called when the button is pressed
buttonPressed();
}
});
Then you would write this method in the same class:
private void buttonPressed() {
System.out.println("Button pressed!");
}
I just whipped up a quick test of this, so I can confirm that this method works.
PS: I would also suggest having the button contain a boolean state instead of checking for the text of the button, if you do intend to keep using the StartButton and associated classes.
I am trying to add an ActionListener to a JButton created in a loop, then call the ActionListener from another class (the controller class), but its not working. I don't know why.
Here is the first class
public class Browse extends JPanel {
private JButton play_lists_btn;
public Browse() {
int increment = 0;
while (increment < 5) {
add(createButton(increment));
increment++;
}
}
private JButton createButton(final int i) {
play_lists_btn = new JButton();
play_lists_btn.setText(" This is " + i);
return play_lists_btn;
}
public void addPlayListener(ActionListener play) {
play_lists_btn.addActionListener(play);
}
public static void main(String args[]) {
Browse b = new Browse();
BrowseController bc = new BrowseController(b);
JFrame frame = new JFrame();
frame.add(b);
frame.setSize(1100, 830);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here is the controller class that calls the button ActionListener, and creates an ActionEvent for the button
public class BrowseController {
private Browse b;
public BrowseController(Browse b) {
this.b = b;
b.addPlayListener(new PlayListener());
}
private class PlayListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String text = (String) e.getActionCommand();
System.out.println(text);
}
}
}
Nothing seems to work. the print statement never show up. please help, because I am trying to achieve the MVC design pattern.
try this,
Move your inner class inside Browse.java and add ActionListener for each and every button created
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Browse extends JPanel {
private JButton [] play_lists_btn=new JButton[5];//define an array of JButtons
public Browse() {
int increment = 0;
while (increment < 5) {
add(createButton(increment));
increment++;
}
}
private JButton createButton(final int i) {
play_lists_btn[i] = new JButton();
play_lists_btn[i].setText(" This is " + i);
return play_lists_btn[i];
}
public void addPlayListener(ActionListener play) {
for(JButton b : play_lists_btn)
b.addActionListener(play);
}
public static void main(String args[]) {
client.Browse b = new client.Browse();
BrowseController bc = new BrowseController(b);
JFrame frame = new JFrame();
frame.add(b);
frame.setSize(1100, 830);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
BrowseController.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BrowseController {
private Browse b;
public BrowseController(Browse b) {
this.b = b;
b.addPlayListener(new PlayListener());
}
private class PlayListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String text = (String) e.getActionCommand();
System.out.println(text);
}
}
}
The code in Browse isn't adding an ActionListener to every JButton created.
private JButton playlistButton;
...
private JButton createButton(final int i) {
// this resets playlistButton every time it's called (before ever adding
// an ActionListener to ANY of the buttons)
playlistButton = new JButton();// creates a NEW JButton EVERY TIME!!!
playlistButton.setText(" This is " + i);
return playlistButton; // why does this method return anything?
}
public void addPlayListener(ActionListener play) {
// this only adds an action listener for the latest value of playlistButton
// (not all of the previously created JButton that you don't have a
// reference to anymore).
playlistButton.addActionListener(play);
}
If you want the Panel to be "separate" from the controller (i.e. MVC), then you'll have to keep track of the state of the Panel. Instead of just storing a single button--you need an array of buttons:
public class Browse extends JPanel{
private final JButton[] btnArr;
public Browse(final int numBtns) {
btnArr = new JButton[numBtns];
for(int i = 0; i < numBtns; ++i) {
btnArr[i] = Browse.createButton(i);
add(btnArr[i]);
}
}
public void addPlayListener(final ActionListener play){
for(final JButton btn : btnArr)
btn.addActionListener(play);
}
private static JButton createButton(final int i) {
// create a new JButton, init it AND set action command (if you're
// going to use it)
final JButton btn = new JButton(" This is " + i);
btn.setActionCommand(btn.getText());
return btn;
}
public static void main(String args[]) {
Browse b = new Browse();
BrowseController bc = new BrowseController(b);
JFrame frame = new JFrame();
frame.add(b);
frame.setSize(1100, 830);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
String text = (String) e.getActionCommand();
System.out.println(text);
}
}