adding listeners to JButton array; - java

I have the following code which creates a JButton array on button click. Ope[] is publically declared in class. I have problem that I got null pointer. That is it doesn't print 2nd in loop ie. doesn't go in inner iteration.
Please tell me how to handle the listeners for array. Thanks in advance.
for( int i=0,y=30; i<counter;i++,y+=15 )
{
open[i]=new JButton( "Open" );
open[i].setBounds( 380, y, 70, 15 );
open[i].addActionListener( this );
panelDisplay.add (open[i] );
System.out.println(""+i);
}
The event handling in actionPerformed function is as follows:
for( int j=0; j<open.length; j++ )
{
System.out.println("1st in a loop"+j);
if( ae.getSource() != null )
{
if( ae.getSource() == open[j] )
{
System.out.println("2nd in a loop" +j);
int id;
String stringid;
System.out.println("open of"+j+"is clicked");
stringid = ""+table.getValueAt(j, 0);
id = Integer.parseInt(stringid);
fetchData(id);
//ae.getSource().equals(null);
}
}
}

JButton inherits "setName" Method from Component. So if you set a name on the Button at initialization
open[i]=new JButton( "Open" );
open[i].setBounds( 380, y, 70, 15 );
open[i].setName("Button"+i);
open[i].addActionListener( this );
panelDisplay.add (open[i] );
System.out.println(""+i);
you can find wich button was pressed in the eventhandling
int buttonNumber = Integer.parseInt(ae.getSource().getName().replace("Button",""))
//... do eventhandling for Button["buttonNumber"]

Related

Unknown number of buttons, how to add a different Event Action to each JavaFX

I have a JavaFX GUI that creates and adds a number of buttons based on the number of teams, these are stored in an ArrayList, this number varies.
Each team has a list of people on a roster.
My issue is I want to write some sort of logic that without first knowing I can add a list of buttons and when clicked each will display their different rosters.
Button getTeamsButton = new Button( "Load Teams and Details" );
getTeamsButton.setOnAction( e -> {
getTeams.scrapeTeams();
if( !getTeams.getTeams().isEmpty() )
{
for( int i = 0; i < getTeams.getTeams().size(); i++ )
{
Button teamName = new Button( getTeams.getTeams().get(i).getTeamName() );
teamNamesButtons.add( teamName );
layout1.getChildren().add( teamNamesButtons.get( i ) );
}
I am able to create the buttons.
getTeamsButton.setDisable( true );
teamNamesButtons.get( 0 ).setOnAction( f -> {
for(int i = 0; i < getTeams.getTeams().get( 0 ).getRoster().size(); i++) {
System.out.println(getTeams.getTeams().get( 0 ).getRoster().get( i ));
}
});
}
} );
And if I specify which item in the list I can print the Roster, how to I explain the logic of the top button is team 0, second is team 1, etc etc?
Any advice would be much appreciated?
It's not entirely clear what you're asking, but maybe this helps.
You already "know" when you create the button which index it has: the index is given by i. So you just have to create an event handler that references that value. The only catch here is that you can't reference a non-final variable (or a variable that can't be made final by simply adding the final keyword) in a lambda expression, so you may need to copy it to a final variable.
E.g.:
Button getTeamsButton = new Button( "Load Teams and Details" );
getTeamsButton.setOnAction( e -> {
getTeams.scrapeTeams();
if( !getTeams.getTeams().isEmpty() ) {
for( int i = 0; i < getTeams.getTeams().size(); i++ ) {
Button teamName = new Button(
getTeams.getTeams().get(i).getTeamName() );
teamNamesButtons.add( teamName );
layout1.getChildren().add( teamNamesButtons.get( i ) );
final int index = i ;
teamName.setOnAction(evt -> {
for (int j = 0 ; j < getTeams.getTeams().get(index).getRoster().size(); j++) {
System.out.println(getTeams.getTeams().get(index).getRoster().get( j ));
}
});
}
}
});
You probably don't really need the index, though; just the relevant data. You haven't shown what's actually in your lists, but assuming you have defined some kind of Team class, you can make this much cleaner with
Button getTeamsButton = new Button( "Load Teams and Details" );
getTeamsButton.setOnAction( e -> {
getTeams.scrapeTeams();
// the if statement here is redundant, if the list is
// empty, the for loop will just iterate zero times....
for( int i = 0; i < getTeams.getTeams().size(); i++ ) {
Team team = getTeams.getTeams().get(i);
Button teamName = new Button(team.getTeamName());
teamNamesButtons.add(teamName);
layout1.getChildren().add(teamName);
teamName.setOnAction(evt -> {
for (int j = 0 ; j < team.getRoster().size(); j++) {
System.out.println(team.getRoster().get( j ));
}
});
}
});
or, using the preferred syntax
Button getTeamsButton = new Button( "Load Teams and Details" );
getTeamsButton.setOnAction( e -> {
getTeams.scrapeTeams();
for( Team team : getTeams.getTeams()) {
Button teamName = new Button(team.getTeamName());
teamNamesButtons.add(teamName);
layout1.getChildren().add(teamName);
teamName.setOnAction(evt -> {
for (Player player : team.getRoster) {
System.out.println(player);
}
});
}
});
(You shouldn't really need the teamNamesButtons list either... note how it's no longer needed in the code above.)

Java - enter multiple values into array via a single textfield [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
With this code, i want to develop a program that enables the user to enter 5 int values into a single textfield. These values will be stored in an array and upon pressing the button, a bar graph will be drawn to represent the entered values. Class BtnHandler handles the button click event and class gegHandler handles the textfield enter event. I can't get the user input to be collected in the array. Here is my code.
package voorbeeld0805;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Vb0805 extends JFrame {
public static void main( String args[] ) {
JFrame frame = new Vb0805();
frame.setSize( 300, 300 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setTitle( "Voorbeeld 0805" );
frame.setContentPane( new Tekenpaneel() );
frame.setVisible( true );
}
}
class Tekenpaneel extends JPanel {
private Staafdiagram staafdiagram;
private JButton knopTeken;
private JTextField gegevensVak;
private JLabel lblNo;
private int[] lengtes = new int [5];
public Tekenpaneel() {
setBackground( Color.ORANGE );
knopTeken = new JButton("Teken");
knopTeken.addActionListener(new BtnHandler());
gegevensVak = new JTextField(5);
gegevensVak.addActionListener(new gegHandler());
lblNo = new JLabel("Enter Value");
add(knopTeken);
add (gegevensVak);
add (lblNo);
}
public void paintComponent( Graphics g ) {
super.paintComponent( g );
if (staafdiagram != null)
{
staafdiagram.teken( g, 50, 250 );
}
this.requestFocusInWindow();
}
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//To test using the first constructor. Works perfectly
/*int [] lengtes = { 144, 98, 117, 130, 172, 173 };
staafdiagram = new Staafdiagram( lengtes, 30 );*/
repaint();
}
}
class gegHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//Here user input should be collected, placed in an array and
//saved in staafdiagram.setLengtes();
for (int i = 0; i < lengtes.length; i++){
lblNo.setText("Next Value Is " + i++);
lengtes[i] = Integer.parseInt( gegevensVak.getText());
gegevensVak.setText("");//clear textfield after entering a value
}
}
}
}
class Staafdiagram {
private int[] lengtes;
private int witruimte;//this generates the spaces between the bars
//First contructor with 2 arguments array en space
public Staafdiagram( int[] lengtes, int witruimte ) {
this.lengtes = lengtes;
this.witruimte = witruimte;
}
//Second constructor with only 1 argument space
public Staafdiagram(int witruimte ) {
this.witruimte = witruimte;
}
//With this, i want the user input to be collected in an array
public void setLengtes(int[] lengtes) {
this.lengtes = lengtes;
}
//To calculate the bar with the highest value
public int bepaalMax(){
int maximum = lengtes [0];
for (int i = 1; i < lengtes.length; i++){
if (lengtes[i] > maximum)
{
maximum = lengtes[i];
}
}
return maximum;
}
//To calculate the bar with the lowest value
public int bepaalMin(){
int minimum = lengtes [0];
for (int i = 1; i < lengtes.length; i++){
if (lengtes[i] < minimum)
{
minimum = lengtes[i];
}
}
return minimum;
}
public void teken( Graphics g, int x, int y ) {
int startX = x;
// Draw the bars
for( int lengte : lengtes ) {
if (lengte == bepaalMax())
g.setColor(Color.red);
else if (lengte == bepaalMin())
g.setColor(Color.green);
else
g.setColor(Color.black);
g.fillRect( x, y - 20 - lengte, 20, lengte );
x += witruimte;
}
// Display the values under the bars
x = startX;
for( int lengte : lengtes ) {
g.drawString( String.format( "%d", lengte ), x, y );
x += witruimte;
}
}
}
If you add an ActionListener on a JTextField, the actionPerformed() method is called when you "action" this field : here is the enter key pressed.
If you want associate the button to your action, you should rather enrich the ActionListener you defined on the JButton to also get the values entered by the user. The idea is chaining the both as both operations should performed one after the other one :
These values will be stored in an array and upon pressing the button,
a bar graph will be drawn to represent the entered values.
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
// collection information from textfield
for (int i = 0; i < lengtes.length; i++){
lblNo.setText("Next Value Is " + i++);
lengtes[i] = Integer.parseInt( gegevensVak.getText());
gegevensVak.setText("");//clear textfield after entering a value
}
// rendering
staafdiagram = new Staafdiagram( lengtes, 30 );*/
repaint();
}
}
Get the input from the text field as text
split to string array
Convert to int
MOdify your code as follows.
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//To test using the first constructor. Works perfectly
/*int [] lengtes = { 144, 98, 117, 130, 172, 173 };
staafdiagram = new Staafdiagram( lengtes, 30 );*/
String textInt=gegevensVak .getText(); //gegevensVak is the name of the textfield you mentioned
String[] strArray = textInt.split();
//now convert the string to int and add to a new array
repaint();
}
}

How to resolve NullPointerException? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I am trying to create a JPanel that asks whether the player wants to hit or stand in a Black Jack game.
public class decisionLayout extends JFrame
{
JPanel decisionPanel;
public JButton buttons[];
private final String names[] = { "YES", "NO" };
final static String ASK_FOR_DECISION = "Decide whether to hit or not.";
public decisionLayout()
{
super( "decisionPanel demo" );
JPanel panel = new JPanel();
JPanel TextFieldPanel = new JPanel();
final JTextField tf = new JTextField();
tf.setText( ASK_FOR_DECISION );
tf.setEditable( false );
TextFieldPanel.add( tf );
// create the decisions
JPanel decisionPlace = new JPanel();
for ( int count = 0; count < buttons.length; count++ )
{
buttons[ count ] = new JButton( names[ count ] );
buttons[ count ].addActionListener(
new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
if( e.getSource() == buttons[ 0 ] )
{
tf.setText( "Yes. You want more cards." );
}
else
{
tf.setText( "No. You do not want more cards." );
}
}
}
);
}
JPanel decisionPanel = new JPanel();
decisionPanel.add( decisionPlace );
panel.add( TextFieldPanel, BorderLayout.PAGE_START );
panel.add( decisionPanel, BorderLayout.CENTER );
}
} `
I do not see why there is a compilation error at line:
for ( int count = 0; count < buttons.length; count++ )
,which is what eclipse keeps telling me. Does anybody have any ideas why this is happening?
public JButton buttons[];
You never initialize your buttons, so when you try to call buttons.length you get an NPE. You probably want to actually place some buttons in that array
You never initialize the buttons[]. buttons[] has no length:
for ( int count = 0; count < **buttons.length**; count++ )

How to account for input errors in calculator program?

I'm writing a calculator program for my java class. I want to account for errors like
User decides to divide by 0. I want the calculator to be able to acknowledge this error and display ERROR.
The user enters 6+7+ and then hits the equal button.
I want, once again, for the calculator to acknowledge that there is an error. I was hoping I could get some hints as to how to go about this. Thanks!
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Calculator
{
JFrame window;
// stuff for top panel
JPanel topPanel;
JTextField expr,result;
JButton equals;
// stuff for bottom panel
JPanel bottomPanel,digitsPanel,opsPanel;
JButton[] digits,ops;
JButton clear, clearEntry;
Container content;
Listener listener;
String[] oplabels = { "+", "-", "/", "*" };
public Calculator()
{
listener = new Listener(); // our Listener class implements ActionListener
window= new JFrame("GUI Calc");
content=window.getContentPane();
content.setLayout( new GridLayout(2,1) );
topPanel=new JPanel();
topPanel.setLayout( new GridLayout(1,3) );
// TOP PANEL WORK
expr = new JTextField( );
equals = new JButton("=");
equals.addActionListener( listener );
result = new JTextField( );
topPanel.add( expr );
topPanel.add( equals );
topPanel.add( result );
// BOTTOM PANEL WORK
bottomPanel = new JPanel();
bottomPanel.setLayout( new GridLayout(1,2) );
digitsPanel = new JPanel();
digitsPanel.setLayout( new GridLayout(4,3) );
opsPanel = new JPanel();
opsPanel.setLayout( new GridLayout(4,1) );
digits = new JButton[12];
ops = new JButton[4];
for (int i=0 ; i<10 ; i++)
{
digits[i] = new JButton( i+"" );
digits[i].addActionListener(listener);
digitsPanel.add( digits[i] );
}
clear = new JButton( "C" );
clearEntry = new JButton( "CE" );
clear.addActionListener(listener);
clearEntry.addActionListener(listener);
digitsPanel.add( clear );
digitsPanel.add( clearEntry);
for (int i=0 ; i<4 ; i++)
{
ops[i] = new JButton( oplabels[i] ) ;
ops[i].addActionListener(listener);
opsPanel.add( ops[i] );
}
bottomPanel.add( digitsPanel );
bottomPanel.add( opsPanel );
content.add( topPanel);
content.add( bottomPanel);
window.setVisible(true);
}
class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Component clicked = (Component) e.getSource();
if ( clicked == equals )
{
result.setText( evaluate( expr.getText() ) );
return;
}
for ( int i=0 ; i<10 ; i++)
{
if ( clicked == digits[i] )
{
expr.setText( expr.getText() + i );
return;
}
}
if ( clicked == clear )
{
expr.setText("0");
return;
// do something
}
/* if (clicked == clearEntry)
{
expr.setText(expr.getDigits[i]);
}
for (int i=0; i < 10; i++)
{
if (clicked == digits[i])
{
int lastValue = clicked;
if(clicked == clearEntry)
{
expr.setText(expr.getText()-clicked);
return;
}
}
} */
for ( int i=0 ; i<4 ; i++ )
{
if(clicked == digits[i])
{
expr.setText(expr.getText() + oplabels[i]);
return;
}
// tack on that operator to the expr string
}
}
String evaluate( String exp )
{
return "NOT WRITTEN YET";
}
}
public static void main(String [] args)
{
new Calculator();
}
}
I'm still working on it. Especially where I'm trying to figure out the clearEntry button so I have put that section as a comment because its still a work in progress.
You can try this:
add a new class(Calculator) member:
Component last_clicked;
Inside Constructor:
last_clicked=null;
Before every return statement of actionPerformed, you can add this:
last_clicked=clicked;
Now, in actionPerformed method, when checking value of clicked, you can do this:
When clicked is '0' & last_clicked is '/', you can display error 1.
When clicked is 'equals' & last_clicked is an operator, you can display error 2.

Can someone help me work out the kinks in my program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have to write a calculator program using the Gui components. I have written the program but I'm having issues with my CE button. It is giving me errors. I'm also getting and error in my for loop where I add the operand labels to the expression. I was just hoping to get some help in fixing these errors. Thank you! Please ignore the comments. They are there for my to keep track of what I have to do.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Calculator
{
JFrame window;
// stuff for top panel
JPanel topPanel;
JTextField expr,result;
JButton equals;
// stuff for bottom panel
JPanel bottomPanel,digitsPanel,opsPanel;
JButton[] digits,ops;
JButton clear, clearEntry;
Container content;
Listener listener;
String[] oplabels = { "+", "-", "/", "*" };
public Calculator()
{
listener = new Listener(); // our Listener class implements ActionListener
window= new JFrame("GUI Calc");
content=window.getContentPane();
content.setLayout( new GridLayout(2,1) );
topPanel=new JPanel();
topPanel.setLayout( new GridLayout(1,3) );
// TOP PANEL WORK
expr = new JTextField( );
equals = new JButton("=");
equals.addActionListener( listener );
result = new JTextField( );
topPanel.add( expr );
topPanel.add( equals );
topPanel.add( result );
// BOTTOM PANEL WORK
bottomPanel = new JPanel();
bottomPanel.setLayout( new GridLayout(1,2) );
digitsPanel = new JPanel();
digitsPanel.setLayout( new GridLayout(4,3) );
opsPanel = new JPanel();
opsPanel.setLayout( new GridLayout(4,1) );
digits = new JButton[12];
ops = new JButton[4];
for (int i=0 ; i<10 ; i++)
{
digits[i] = new JButton( i+"" );
digits[i].addActionListener(listener);
digitsPanel.add( digits[i] );
}
clear = new JButton( "C" );
clearEntry = new JButton( "CE" );
clear.addActionListener(listener);
clearEntry.addActionListener(listener);
digitsPanel.add( clear );
digitsPanel.add( clearEntry);
for (int i=0 ; i<4 ; i++)
{
ops[i] = new JButton( oplabels[i] ) ;
ops[i].addActionListener(listener);
opsPanel.add( ops[i] );
}
bottomPanel.add( digitsPanel );
bottomPanel.add( opsPanel );
content.add( topPanel);
content.add( bottomPanel);
window.setVisible(true);
}
class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Component clicked = (Component) e.getSource();
if ( clicked == equals )
{
result.setText( evaluate( expr.getText() ) );
return;
}
for ( int i=0 ; i<10 ; i++)
{
if ( clicked == digits[i] )
{
expr.setText( expr.getText() + i );
return;
}
}
if ( clicked == clear )
{
expr.setText("0");
return;
// do something
}
for (int i=0; i < 10; i++)
{
if (clicked == digits[i])
{
int lastValue = i;
return;
}
}
if ( clicked == clearEntry )
{
expr.setText(expr.getText() - lastValue);
return;
// do something
}
for ( int i=0 ; i<4 ; i++ )
{
if(clicked == oplabels[i])
{
expr.setText(expr.getText + oplabels[i]);
return;
}
// tack on that operator to the expr string
}
}
String evaluate( String exp )
{
return "NOT WRITTEN YET";
}
}
public static void main(String [] args)
{
new Calculator();
}
}
Problem #1
The compiler is complaining about expr.setText(expr.getText() - lastValue); because lastValue is undefined.
Having a close look at the code, the only place that lastValue is defined is within the for-loop before the if statement...but the next issues thereturn` statement following it's decleration...
for (int i = 0; i < 10; i++) {
if (clicked == digits[i]) {
int lastValue = i;
return;
}
}
if (clicked == clearEntry) {
expr.setText(expr.getText() - lastValue);
return;
// do something
}
This not only makes the lastValue useless, but it's unlikely that the if statement would ever be reached...
Problem #2
for (int i = 0; i < 4; i++) {
if (clicked == oplabels[i]) {
expr.setText(expr.getText + oplabels[i]);
return;
}
// tack on that operator to the expr string
}
clicked is defined as Component clicked = (Component) e.getSource(); and oplables are defined as String[] oplabels = {"+", "-", "/", "*"};. String and Component are not comparable (also, you want expr.getText() not expr.getText).
I think you want to do something more like...
if (clicked instanceof JButton) {
JButton btn = (JButton)clicked)
for (int i = 0; i < oplabels.length; i++) {
if (oplabels[i].equals(btn.getText()) {
//...
}
}
}
Line 128: clicked is a Component and oplabels[i] is a string - you can't compare them directly.
Line 130: Missing () on getText() call.

Categories