-1

I am trying to make a method that disables JButtons.

The JButtons are in an array in the form of a grid, JButton [int][int] and the integers are supposed to be coordinates.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;


public class BS {

public static JFrame f = new JFrame("BS");



public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        initializeGui();
      }
    });

}

static void initializeGui() {

     JPanel gui = new JPanel(new BorderLayout(3,1));
//This is the array of the JButtons in the form of a grid
     final JButton[][] coordinates = new JButton[15][15];
     JPanel field;


    // set up the main GUI
    gui.setBorder(new EmptyBorder(5, 5, 5, 5));
    field = new JPanel(new GridLayout(0, 15));

    field.setBorder(new CompoundBorder(new EmptyBorder(15,15,15,15),new LineBorder(Color.BLACK)));

    JPanel boardConstrain = new JPanel(new GridBagLayout());
    boardConstrain.add(field);
    gui.add(boardConstrain);

//The making of the grid
    for (int ii = 0; ii < coordinates.length; ii++) {
        for (int jj = 0; jj < coordinates[ii].length; jj++) {
            JButton b = new JButton();

            ImageIcon icon = new ImageIcon(
                    new BufferedImage(30, 30, BufferedImage.TYPE_INT_ARGB));
            b.setIcon(icon);

            coordinates[jj][ii] = b;
            field.add(coordinates[jj][ii]);
        }
    }

    f.add(gui);
    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);              
    f.pack();
    f.setMinimumSize(f.getSize());
    f.setVisible(true);
}

}

Giacomo
  • 29
  • 5
  • Call [`JButton#setEnabled(false)`](https://docs.oracle.com/javase/7/docs/api/javax/swing/AbstractButton.html#setEnabled(boolean)) in the `JButton` you want to disable. Now for better help sooner post a proper [mcve] that shows your effort trying to solve the issue yourself – Frakcool Apr 05 '18 at 15:11
  • @Frakcool sorry for not posting the full code, the question sounded simple in my head for some reason :) – Giacomo Apr 05 '18 at 15:32
  • It's a simple problem, but in this site you must provide your code or else your code is taken as "too-broad". When are you trying to disable a `JButton`? When clicked? – Frakcool Apr 05 '18 at 15:37
  • @Frakcool When clicked would be more efficient if it is possible.But when clicked I would like for a given number of buttons following it to get disabled as well. – Giacomo Apr 05 '18 at 15:42
  • Explain yourself, what you mean by *"a given number of buttons following it to get disabled as well"* How many? Just the same row? Next row? Columns? How? Btw, using short names for class names or any other variable might be confusing in bigger programs (`BS` what does that mean?) – Frakcool Apr 05 '18 at 15:43
  • @Frakcool Let's say I press a button and a second one, all button between these two buttons are disabled. So that the user has the possibility to choose if it is a row or column (vertical or horizontal). Sorry if I am being unclear. I basically want to disable a column or row of buttons, but instead of doing one by one I just press the start button and end button of line of buttons I want to disable. – Giacomo Apr 05 '18 at 15:49
  • Ok, got it, let me try something – Frakcool Apr 05 '18 at 15:54

1 Answers1

1

I did some changes in your code:

  1. public static JFrame f = new JFrame("BS"); JFrame shouldn't be static and should have a more meaningful name (like frame for example).

  2. final JButton[][] coordinates = new JButton[15][15]; moved this array as a class member and made it non final and also changed the name to buttons as it's easier to know what it is (coordinates to me, sounds more like an array of Point or int)

After that I added an ActionListener, see How to use Actions tutorial.

private ActionListener listener = e -> {
    //Loops through the whole array in both dimensions
    for (int i = 0; i < buttons.length; i++) {
        for (int j = 0; j < buttons[i].length; j++) {
            if (e.getSource().equals(buttons[i][j])) { //Find the JButton that was clicked
                if (isStartButton) { //startButton is a boolean variable that tells us if this is the first button clicked or not
                    startXCoord = i;
                    startYCoord = j;
                } else {
                    endXCoord = i;
                    endYCoord = j;
                    disableButtons(); //Only when we have clicked twice we disable all the buttons in between
                }
                isStartButton = !isStartButton; //In every button click we change the value of this variable
                break; //No need to keep looking if we found our clicked button. Add another one with a condition to skip the outer loop.
            }
        }
    }
};

And a method called disableButtons() which disables all the buttons between the 2 clicked buttons:

private void disableButtons() {
    compareCoords(); //This method checks if first button clicked is after 2nd one.
    for (int i = startXCoord; i <= endXCoord; i++) {
        for (int j = startYCoord; j <= endYCoord; j++) {
            buttons[i][j].setEnabled(false); //We disable all buttons in between
        }
    }
}

At the end our code ends like this:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class DisableButtonsInBetween {

    private JFrame frame = new JFrame(getClass().getSimpleName());
    private JButton[][] buttons;

    private int startXCoord = -1;
    private int startYCoord = -1;
    private int endXCoord = -1;
    private int endYCoord = -1;
    private boolean isStartButton = true;

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

    void initializeGui() {
        JPanel gui = new JPanel(new BorderLayout(3, 1));
        // This is the array of the JButtons in the form of a grid
        JPanel pane;
        buttons = new JButton[15][15];

        // set up the main GUI
        gui.setBorder(new EmptyBorder(5, 5, 5, 5));
        pane = new JPanel(new GridLayout(0, 15));

        pane.setBorder(new CompoundBorder(new EmptyBorder(15, 15, 15, 15), new LineBorder(Color.BLACK)));

        JPanel boardConstrain = new JPanel(new GridBagLayout());
        boardConstrain.add(pane);
        gui.add(boardConstrain);

        // The making of the grid
        for (int ii = 0; ii < buttons.length; ii++) {
            for (int jj = 0; jj < buttons[ii].length; jj++) {
                buttons[jj][ii] = new JButton();

                ImageIcon icon = new ImageIcon(new BufferedImage(30, 30, BufferedImage.TYPE_INT_ARGB));
                buttons[jj][ii].setIcon(icon);
                buttons[jj][ii].addActionListener(listener);

                pane.add(buttons[jj][ii]);
            }
        }

        frame.add(gui);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setMinimumSize(frame.getSize());
        frame.setVisible(true);
    }

    //The ActionListener is what gets called when you click a JButton
    private ActionListener listener = e -> {
        //These for loops are done to identify which button was clicked.
        for (int i = 0; i < buttons.length; i++) {
            for (int j = 0; j < buttons[i].length; j++) {
                if (e.getSource().equals(buttons[i][j])) {
                    if (isStartButton) {
                        //We save the coords of the 1st button clicked
                        startXCoord = i;
                        startYCoord = j;
                    } else {
                        //We save the coords of the 2nd button clicked and call the disableButtons method
                        endXCoord = i;
                        endYCoord = j;
                        disableButtons();
                    }
                    isStartButton = !isStartButton;
                    break;
                }
            }
        }
    };

    //This method disables all the buttons between the 2 that were clicked
    private void disableButtons() {
        compareCoords();
        for (int i = startXCoord; i <= endXCoord; i++) {
            for (int j = startYCoord; j <= endYCoord; j++) {
                buttons[i][j].setEnabled(false);
            }
        }
    }

    //This method compares the coords if the 2nd button was before (in its coords) than the 1st one it switched their coords
    private void compareCoords() {
        if (endXCoord < startXCoord) {
            int aux = startXCoord;
            startXCoord = endXCoord;
            endXCoord = aux;
        }
        if (endYCoord < startYCoord) {
            int aux = startYCoord;
            startYCoord = endYCoord;
            endYCoord = aux;
        } 
    }
}

enter image description here

I hope this is what you were trying to do... if not please clarify.

I do not have the arrow operator, " -> ". I think it requires a higher Java. Is there a way to replace this?

For Java 7 and lower use this for the ActionListener:

private ActionListener listener = new ActionListener() {    
    @Override
    public void actionPerformed(ActionEvent e) {
        for (int i = 0; i < buttons.length; i++) {
            for (int j = 0; j < buttons[i].length; j++) {
                if (e.getSource().equals(buttons[i][j])) {
                    if (isStartButton) {
                        startXCoord = i;
                        startYCoord = j;
                    } else {
                        endXCoord = i;
                        endYCoord = j;
                        disableButtons();
                    }
                    isStartButton = !isStartButton;
                    break;
                }
            }
        }
    }
};
Frakcool
  • 10,915
  • 9
  • 50
  • 89
  • I do not have the arrow operator, " -> ". I think it requires a higher Java. Is there a way to replace this? – Giacomo Apr 05 '18 at 16:39
  • I am getting the following error when the ActionListener is added: The type new ActionListener(){} must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent) – Giacomo Apr 05 '18 at 16:51
  • Did you added the 2 next lines? Like `@Override` and `public void actionPerformed(ActionEvent e) {` as I did in the edited code? Just copy-paste the whole `ActionListener` and it should be ok – Frakcool Apr 05 '18 at 16:53
  • I fixed it by importing `java.awt.event.ActionEvent` and removing the override – Giacomo Apr 05 '18 at 16:58
  • Would you mind adding some sort of comments above the methods, I am trying to understand it. Thanks! – Giacomo Apr 05 '18 at 17:02
  • What methods? I explained everything in the snippets above... What don't you understand? – Frakcool Apr 05 '18 at 17:03
  • I did try to explain what the methods do, I don't know if it helps but without knowing what you don't understand I can't really explain more – Frakcool Apr 05 '18 at 17:10
  • Never mind, I just needed to read through the code several times. Thank you for the help!! – Giacomo Apr 05 '18 at 17:13
  • If this answer solves your question be sure to [accept it](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – Frakcool Apr 05 '18 at 17:13