Hi guys. I'm working on my school project. My asigment is to make a piano game. The program works fine but my work stopped when i came to a problem. I would like to put the integers, which i get from pushing the specific JButton, into an array. For example if i would press JButton 3, JButton 4, and JButton 1, i would get in my array [3,4,1]. Please help me. Best regards.
Here's my code:

import javax.swing.*;
import javax.sound.sampled.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.Color;

class vse_v_enem extends JFrame implements ActionListener
{

    public static void main(String [] arg){
        new vse_v_enem();              
    }    

    public vse_v_enem(){
        initSounds();
    }

    protected void initSounds(){
        sounds();
        zacetek();        
    }

    public void sounds(){

        for(int i=1;i<=13;i++)
             try{
                audioIn[i] = AudioSystem.getAudioInputStream(vse_v_enem.class.getResource("zvoki/"+i+".wav"));
                //System.out.println("zvoki/"+i+".wav.wav");
            } catch(javax.sound.sampled.UnsupportedAudioFileException e){

            } catch(Exception e){
                System.out.println("Hm....  something went wrong");
            }

    }

    public void zacetek (){ 
        JFrame okvir = new JFrame("Klaviaturska zabava");
        okvir.setBounds(500,400,416,214);
        JLayeredPane panel = new JLayeredPane(); 
        okvir.add(panel); 

        //int f[] = igra();        
        /**naredi crne tipke*/
        int crnih = 5; 
        int sirina = 30; 
        int visina = 113;        
        for(int i = 0; i<crnih;i++){
            JButton b = new JButton(""+(i+1));
            b.setFont(b.getFont().deriveFont((float)11));
            b.setForeground(Color.WHITE);
            b.setBackground(Color.BLACK);
            b.setSize(sirina,visina);             
            b.setLocation(i*50 + (sirina*3)-5,0);            
            b.addActionListener(this);

            panel.add(b,1,-1);

        }
        /** naredi bele tipke*/
        int belih = 8; 
        int sirina1 = 50; 
        int visina1 = 176;

        for (int i = 6; i<belih+6; i++){            

            JButton b = new JButton(""+i);
            b.setBackground(Color.WHITE);
            b.setLocation((i-6)*sirina1,0);   
            b.setSize(sirina1,visina1);
            b.addActionListener(this);                    
            panel.add(b,0,-1);

        }        

        okvir.setVisible(true);   
    }    

    public void predvajajZvBesedilo(AudioInputStream audioIn){  
        sounds();

        try {
            clip = AudioSystem.getClip();
            clip.open(audioIn);            
        } catch(Exception e) {};
        clip.setFramePosition(0); 
        clip.start();
    }

    public void tabela(int tab){              
    }

    public void actionPerformed(ActionEvent e){

        JButton tempButton = (JButton)e.getSource();
        System.out.print(  tempButton.getText() + " " );           

        int clipNr = Integer.valueOf(tempButton.getText());
        //tabela(tab[clipNr]);
        predvajajZvBesedilo( audioIn[clipNr]);

    }

    public int[] igra(){        
        int t [] = {4,5,8,6};
        System.out.print("[ ");
        for(int i = 0; i < t.length; i++){
            //t[i] = (int)(Math.random()*13+1);            
            System.out.print(t[i]+" "); 

        }      
        System.out.print("] ");
        System.out.println();
        System.out.println();

        return t;
    }

    public void delay (int i){
        try {
            Thread.sleep(i*1000);
        } catch(InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }

    private JFrame okvir = null;
    private Clip clip = null;
    int [] tab = new int [igra().length];

    AudioInputStream audioIn[] = new AudioInputStream[14];

}

Arrays are not easy to use when you want to have a growing list of values like that. You need to start with a large array, and have a separate counter that tells you how many values you have actually used so far (initially zero). The counter then tells you where to store the next value. When the array is full you need to create new bigger array, and copy all your existing values into that.
Java provides List classes that make it really easy. Have a look at the ArrayList class in the API docs.

and storing the values is as easy as just saving values in an array/list. let's assume you take James' advice and use a list:

@Override
public void actionPerformed(ActionEvent event){
 // if those buttons have the numbers as text on them
  JButton b = (JButton)event.getSource();
  char text = b.getText().getChar(0);
  if ( Character.isDigit(text))
    myList.add(new Character(text));
}

now, this code assumes you only have 0 to 9 buttons, and no buttons with a text like "6. indexes"
it also assumes you have only JButtons using that class as actionlistener.

if the text are not the digits, you can always do something like this:

@Override
public void actionPerformed(ActionEvent event){
    if ( event.getSource() == myButton1)
      myList.add(new Character('1'));
    else if (event.getSource() == myButton2)
      myList.add(new Characer('2'));
    // and so on
}

a third option would be: store the JButtons in a certain array, and use it's indices to get the numeric value to store.

It's a common requirement to associate a value or values with a button, and the previous post shows some of the techniques that people often use to do that.

But there's a better way that most people don't know about....
All JComponents have a "client property" Map where you can store and retrieve anything you like as key/value pairs. So, for example, if you want to associate chars with buttons you can set their client properties like

buttonThree.putClientProperty("character", '3');

then you can retrieve that with something like

char c = (char) ((JButton) event.getSource()).getClientProperty("character");

thank you for your help, but i have solved my problem with:

JButton tempButton = (JButton)e.getSource();
    System.out.print(  tempButton.getText() + " " );           

    int clipNr = Integer.valueOf(tempButton.getText()); 
if(e.getSource() == button1){
array[i] = clipNr;
    i++;}

OK. But just for anyone else who comes across this thread, I want to show another solution that does not require specific text on the buttons (ie will work in Arabic, Hebrew, Chinese etc and with icons on the buttons instead of text) and also avoids the monster actionPerformed that has to deal with every button in one huge error-prone method.

First create a little action listener inner class that has the required number as an instance variable that you can set in the constructor. In its actionPeformed store the number in the array:

    class myListener implements ActionListener {

        private final int number;

        myListener(int number) {
            this.number = number;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            array[i++] = number;
        }
    }

now simply add an instance of this to each button, passing the required number...

buttonOne.addActionListener(new myListener(1));
buttonTwo.addActionListener(new myListener(2));
...

That's all!

Edited 3 Years Ago by JamesCherrill

Hi JamesC,
Your piece of code here interests me.
How would I go about setting a limit to the array size (so that the program stops after say 6 inputs fron the Jbutton), and than also printing the array?
Thanks in advance.

Have a counter that you increment each time the button's actionlistener is called. Test it each time. When it reaches the limit print the array and stop.

Thanks.
Am I on the right track with the use of this in the following code?
Rather new to coding and posting here, so apolgies for any rookie errors.

package roundScore;

import java.awt.EventQueue;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionEvent;

import javax.swing.JTextField;
import javax.swing.SwingConstants;
import java.awt.Font;

public class RoundScoreUI {

    public JFrame frmForeplay;
    private JTextField RndScoreTxt;

    class RndListener implements ActionListener {

        int i;
        int[] rndArray;

        private final int RndScore;

        RndListener(int number) {
            this.RndScore = number;          
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            rndArray[i++] = RndScore;
        }
    }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    RoundScoreUI window = new RoundScoreUI();
                    window.frmForeplay.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * Create the application.
     */
    public RoundScoreUI() {
        initialize();

    }
    /**
     * Initialize the contents of the frame.
     */
    public void initialize() {
        frmForeplay = new JFrame();
        frmForeplay.setTitle("ForePlay");
        frmForeplay.setBounds(100, 100, 399, 526);
        frmForeplay.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmForeplay.getContentPane().setLayout(null);

        JButton RndScore01 = new JButton("1");
        RndScore01.addActionListener(new RndListener(1) {
            public void actionPerformed(ActionEvent e) {

                String EnterNumber = RndScoreTxt.getText() + RndScore01.getText();
                RndScoreTxt.setText(EnterNumber);
            }           
        });
        RndScore01.setBounds(28, 181, 100, 58);
        frmForeplay.getContentPane().add(RndScore01);

        JButton RndScore02 = new JButton("2");
        RndScore02.addActionListener(new RndListener(2) {
            public void actionPerformed(ActionEvent e) {

                String EnterNumber = RndScoreTxt.getText() + RndScore02.getText();
                RndScoreTxt.setText(EnterNumber);
            }
        });
        RndScore02.setBounds(138, 181, 100, 58);
        frmForeplay.getContentPane().add(RndScore02);

        RndScoreTxt = new JTextField();
        RndScoreTxt.setFont(new Font("Tahoma", Font.BOLD, 30));
        RndScoreTxt.setHorizontalAlignment(SwingConstants.CENTER);
        RndScoreTxt.setBounds(216, 16, 146, 76);
        frmForeplay.getContentPane().add(RndScoreTxt);
        RndScoreTxt.setColumns(10);

    }
}       

You are creating anonymous inner classes that subclass RndListener - they override the actionPerformed method so the RndListener become redundant. Either piut your code in RndListener in some general form that works for all buttons, or use anonymous inner class and forget RndListener.

It's strongly recommended to use a @Override annotation on methods that override a superclass - it allows the compiler to check that you have done it correctly, and alerts any reader to what you are doing.

ps: Better answer, assuming your Java is not hoplessly out of date, is to use a lambda expression rather than an anonymous inner class for action listeners

Using a null layout is generally a bad idea. Run your code on a machine with a different screen resolution or font size and your window gets messed up. That's why people use layout managers. I know that learning to use layout managers is a pain, but it's worth it.

Edited 3 Months Ago by JamesCherrill

my two cents: since you are trying to store an element in an array which you don't initialize, you're bound to run into compile time problems.

as James said: Java8 brought a lot improvements to the language, so if you're just starting to learn, it would be recommended to learn the current version rather than an older version, but, either way: don't go for UI 's or something similar before you 've got the hang of the basics.

Thanking you so kindly.
I certainly think its back to the books for me to really understand the fundamentals. Jumped the gun and went way too deep. Crawl before walking.....

Edited 3 Months Ago by Shaun_4