Why is the ActionListener not working with the buttons in Java GUI?

46 Views Asked by At

I'm working on a Java GUI application, and I'm having trouble getting the ActionListener to work properly with my buttons. When I click on the buttons, nothing happens, and the corresponding methods in my class are not being executed. I'm not sure what I'm doing wrong. Here are the concerned classes (particularly "Draw" and "DrawGUI") of my code:

`
public class Draw {
    private static final Object QUIT = null;
    private static final Object CLEAR = null;
    private static final Object SAVE = null;
    private static final Object AUTODRAW = "autoDraw";
    public Graphics g;
    protected DrawGUI window;

    public void doCommand(String command) {
        if (command.equals(CLEAR)) {
            window.clear();
        } else if (command.equals(QUIT)) {
            window.dispose();
            System.exit(0);
        } else if (command.equals(SAVE)) {
            Image img = window.createImageFromPanel();
            try {
                writeImage(img, "test.bmp");
            } catch (IOException e) {
                System.err.println("Not working");
            }
        } else if (command.equals(AUTODRAW)) {
            autoDraw();
        }
    }

    private static final long serialVersionUID = 1L;
    public static final int WIDTH = 800;
    public static final int HEIGHT_DEFAULT = 400;

    public static final String SCRIBBLE = "Scribble";
    public static final String RECTANGLE = "Rectangle";
    public static final String OVAL = "Oval";
    public static final String BLACK = "Black";
    public static final String GREEN = "Green";
    public static final String RED = "Red";
    public static final String BLUE = "Blue";
    public static final String CLEAR = "Clear";
    public static final String QUIT = "Quit";
    public static final String SAVE = "Save";
    public static final String AUTODRAW = "autoDraw";

    private final Draw logic;
    private Color color;
    private final DrawingPanel drawingPanel;

    public DrawGUI(Draw logic) {
        super("Draw");
        this.logic = logic;
        color = Color.black;
        drawingPanel = new DrawingPanel();

        setSize(WIDTH, HEIGHT_DEFAULT);

        JButton clear = new JButton(CLEAR);
        JButton quit = new JButton(QUIT);
        JButton save = new JButton(SAVE);
        JButton autodraw = new JButton(AUTODRAW);
        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 5));
        clear.addActionListener(e -> logic.doCommand(CLEAR));
        quit.addActionListener(e -> logic.doCommand(QUIT));
        save.addActionListener(e -> logic.doCommand(SAVE));
        autodraw.addActionListener(e -> logic.doCommand(AUTODRAW));

        setLayout(new BorderLayout());
        topPanel.add(save);
        topPanel.add(autodraw);
        topPanel.add(new JLabel("Shape:"));
        topPanel.add(shape_chooser);
        topPanel.add(new JLabel("Color:"));
        topPanel.add(color_chooser);
        topPanel.add(clear);
        topPanel.add(quit);
        add(topPanel, BorderLayout.NORTH);
        add(drawingPanel, BorderLayout.CENTER);

        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                DrawGUI.this.logic.doCommand("quit");
            }

        });

        this.setBackground(Color.white);
        this.setVisible(true);

    }
`

I already tried to "debug" the "doCommand" method using System.out.println and what I found out is that only when clicking "autoDraw" the sentence "autoDraw was pressed" is printed to the console. When clicking the rest of the buttons nothing is printed to the console. Only when I close the application window via the macOS menu, "Quit button was pressed" is output on the console, not via clicking the Quit button itself.

2

There are 2 best solutions below

0
davidalayachew On BEST ANSWER

I'm going to edit this into a real answer later, but shot in the dark.

Change this line below.

if (command.equals(CLEAR)) {

Change it to be like this instead.

if (command.equals(DrawGUI.CLEAR)) {

You may need to do some imports.

1
Jesse Barnum On

This is happening because in this section, the final variables CLEAR, QUIT, SAVE are initialized to null, so your if comparison is always false. A decent IDE like IntelliJ will spot this problem and warn you about it.

I think you might have gotten mixed up because your Draw has these variables (where they are null), and the DrawGUI class also has these variables (where they have values), and you're comparing the two variables to each other. Get rid of the variables in the Draw class so that you're comparing the same variable to itself.

public void doCommand(String command) {
    if (command.equals(CLEAR)) {
        window.clear();
        System.out.println("CLEAR button clicked");
    } else if (command.equals(QUIT)) {
        window.dispose();
        System.out.println("QUIT button clicked");
        System.exit(0);
    } else if (command.equals(SAVE)) {
        Image img = window.createImageFromPanel();
        try {
            writeImage(img, "hallo.bmp");
            System.out.println("SAVE button clicked");
        } catch (IOException e) {
            System.err.println("Not working");
        }
    } else if (command.equals(AUTODRAW)) {
        autoDraw();
        System.out.println("AUTODRAW button clicked");
    }
}

P.S. - Stylistically, I don't love how you're running everything through a doCommand() method with a parameter used to dispatch which action to take. If it were me, I would just have a different method for each of the actions and just call those methods from the action listeners. That way you can get rid of all these variables, you don't need to do any comparison if/else-if stuff at all, and this problem wouldn't have occurred.