AnchovyLegend
AnchovyLegend

Reputation: 12537

JButton GUI program where buttons change based on loop iteration

I am trying to create a gui program where the JButtons are in a loop and they change with every iteration. I am having trouble achieving this and I don't understand why, it seems like it shouldn't be a problem, but no matter what I tried, my "q" variable never increments ...

in some instances I was able to get rid of all the errors but my do-while loop never executes. In the example below, I am getting the following error: "Cannot refer to a non-final variable q inside an inner class defined in a different method".

I have been trying to figure this out for quite a while now and I appreciate any advice.

Thanks in advance.

Here is my code (note my q variable):

public class MyClass extends JFrame{
        private JTextField item1;
        private JTextField item2;
        private JTextField item3;
        private JTextField item4;
        private JTextField item5;
        private JButton button1 = new JButton("Process Item #1");
        private JButton button2 = new JButton("Confirm Item #1");
        private JButton button3 = new JButton("View Order");
        private JButton button4 = new JButton("Finish Order");
        private JButton button5 = new JButton("New Order");
        private JButton button6 = new JButton("Exit");
        private Scanner x;
        private int exitFlag = 0;
        public String[] idArray = new String[10];
        public String[] recordArray = new String[10];
        public String[] priceArray = new String[10];

        public void openFile(){
            try{
                x = new Scanner(new File("inventory.txt"));
                x.useDelimiter(",|" + System.getProperty("line.separator")); 
            }
            catch(Exception e){
                System.out.println("Could not find file");
            }
        }
        public void readFile(){
            int i=0;
            while(x.hasNext()){
                idArray[i] = x.next();
                recordArray[i] = x.next();
                priceArray[i] = x.next();
                i++;
            }
        }
        public MyClass(){
            super("Matt's World of Music");
            setLayout(new FlowLayout());
            Box itemBox = Box.createVerticalBox();
            Box itemBox2 = Box.createHorizontalBox(); 

            JLabel label1 = new JLabel("Enter number of items in this order:");
            JLabel label2 = new JLabel("Enter CD ID for Item #1:");
            JLabel label3 = new JLabel("Enter quantity for Item #1:");
            JLabel label4 = new JLabel("Item #1 info:");
            JLabel label5 = new JLabel("Order subtotal for 0 item(s):");

            item1 = new JTextField(10);
            item2 = new JTextField(10);
            item3 = new JTextField(10);
            item4 = new JTextField(10);
            item5 = new JTextField(10);

            itemBox.add(label1);
            itemBox.add(item1);
            itemBox.add(label2);
            itemBox.add(item2);
            itemBox.add(label3);
            itemBox.add(item3);
            itemBox.add(label4);
            itemBox.add(item4);
            itemBox.add(label5);
            itemBox.add(item5);
            itemBox2.add(button1);
            itemBox2.add(button2);
            itemBox2.add(button3);
            itemBox2.add(button4);
            itemBox2.add(button5);
            itemBox2.add(button6);
            itemBox.add(itemBox2);
            add(itemBox);
            button2.setEnabled(false);
            button3.setEnabled(false);
            button4.setEnabled(false);
            item4.setEditable(false);
            item5.setEditable(false);

            //*** NOTE Q VARIABLE ****//
            int q=0;


            do{
                //Process Item

                button1.addActionListener(new ActionListener(){
                   public void actionPerformed(ActionEvent e){
                      String y = item1.getText();
                      MyClass obj = new MyClass();
                      button1.setEnabled(false);
                      button2.setEnabled(true);

                      obj.openFile();
                      obj.readFile();


                      //start loop
                      for(int i=0; i < obj.idArray.length; i++){
                          if(item2.getText().equals(obj.idArray[i])==true){
                              //set item4 text field to price id and other details
                              item4.setText(obj.idArray[i] + " " + obj.recordArray[i] + " $" + obj.priceArray[i].replaceAll("\\s",""));

                              //add to cart

                          }
                       }
                      //*** NOTE Q VARIABLE ****//
                      q++;

                    }
                });
                //Confirm Item
                button2.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e){
                        //Execute when button is pressed
                        JOptionPane.showMessageDialog(null, "Item #1 Accepted");
                    }
                });
                //View Order
                button3.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e){
                        //Execute when button is pressed
                        System.out.println("View Order");
                    }
                });
                //Finish Order
                button4.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e){
                        //Execute when button is pressed
                        System.out.println("Finish Order");
                    }
                });
                //New Order
                button5.addActionListener(new ActionListener(){
                   public void actionPerformed(ActionEvent e){
                       //Execute when button is pressed
                       System.out.println("New Order");
                   }
                });
                //Quit
                button6.addActionListener(new ActionListener(){
                   public void actionPerformed(ActionEvent e){

                       //exit program

                   }
                });
            }while(q < Integer.parseInt(item1.getText()));
        }      
}

Upvotes: 0

Views: 973

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

Consider making a field that holds the value of whatever state you want your button to reflect, changing this field on button press, and then changing your button's text with this field. For example:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class ChangeButton extends JPanel {
   private int buttonCount = 1;
   private JButton button = new JButton();

   public ChangeButton() {
      add(button);
      button.setText(makeButtonText());

      button.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent evt) {
            JButton btn = (JButton) evt.getSource();
            btn.setText(makeButtonText());
         }
      });
   }

   private String makeButtonText() {
      String buttonText = "Process number " + buttonCount;
      buttonCount++;
      return buttonText;
   }

   private static void createAndShowGui() {
      ChangeButton mainPanel = new ChangeButton();

      JFrame frame = new JFrame("ChangeButton");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Or you could hold the field inside of the ActionListener itself:

  button2.setAction(new AbstractAction("Process item 1") {
     private int button2Count = 2;

     @Override
     public void actionPerformed(ActionEvent evt) {
        JButton btn = (JButton) evt.getSource();
        btn.setText(makeButton2Text());
     }

     private String makeButton2Text() {
        String button2Text = "Process item " + button2Count;
        button2Count++;
        return button2Text;
     }


  });

Upvotes: 1

Dan D.
Dan D.

Reputation: 32391

The code below is the way to handle the button press event.

button1.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e){
    ...
  }
});

However, this is an inner class located inside the class constructor. In such cases, when using in an inner class a local variable initialized inside the constructor or insider a method, the variable must be declared final. However, you cannot declare it final because you want to increment it.

Anyway, incrementing it inside the actionPerformed method is wrong. As I said before, that code executes when the button is pressed.

Upvotes: 1

Related Questions