Ilyas Saleem Khurshid
Ilyas Saleem Khurshid

Reputation: 67

Buttons and paint method

I'm having trouble with my buttons. I know they're working because I've tested them out by exiting the problem through System.exit. Here is what my output looks like:

https://i.sstatic.net/PKyDq.jpg

When I click the close button, the handle on the switch should redraw to the other side and the close button should change to open. When I click the open button, it should do the opposite. However, the buttons aren't doing anything. What am I doing wrong?

public class ProgrammingAssignment2 {

public static void main(String[] args) {

    boolean ison = false;

    // Objects
    Circuit circuitObject = new Circuit();
    Controller controllerObject = new Controller();
    Draw drawObject = new Draw();
    AllListeners listenerObject = new AllListeners();
    drawObject.window();

    circuitObject.buttons(drawObject, ison);
    controllerObject.openFile("Programming Assignment 2 Data.txt", drawObject);
}
}

Class circuit just creates the buttons

import javax.swing.JButton;

public class Circuit {

public void buttons(Draw drawObject, boolean ison) {
    AllListeners listenerObject = new AllListeners();

    if (ison == true) {

        JButton openButton = new JButton("Close");
        openButton.addActionListener(listenerObject);
        openButton.setBounds(200, 100, 50, 20);
        drawObject.add(openButton);
    } else if (ison == false) {

        JButton closeButton = new JButton("Open");
        closeButton.addActionListener(listenerObject);
        closeButton.setBounds(50, 100, 50, 20);
        drawObject.add(closeButton);
    }
}
}

Draw class does most of the work. It creates all the graphics and reads in a text file that has the titles of each object(like switch and lightbulb).

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.JFrame;
import java.awt.Graphics;

public class Draw extends JFrame {

private String[] line = new String[5];
private int counter = 0;
private boolean ison;

public void window() {

    setSize(500, 500);
    setTitle("Programming Assignment 2");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

public void readFile(String filename) {

    counter = 1;
    BufferedReader br = null;

    try {
        br = new BufferedReader(new FileReader(filename));


        for (int i = 0; i < 4; i++) {
            line[i] = br.readLine();
        }

    } catch (FileNotFoundException e) {
        String error = "File was not found";
        System.out.println(error.toString());
        System.out.println("or could not be opened.");
    } catch (IOException e) {
        System.out.println("Error reading from file.");
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            System.out.println("Error closing file.");
        }
    }
}

public void paint(Graphics g) {
    Circuit circuitObject = new Circuit();
    super.paint(g);

    if (ison == true) {
        turnon(g);
        circuitObject.buttons(this, ison);
    } else {
        turnoff(g);
    }
}

public void setisOn() {
    ison = true;
}

public void setisOff() {
    ison = false;
}

public void turnoff(Graphics g) {
    // Title
    g.drawString(line[0], 150, 40);

    //Switch
    g.drawString(line[2], 130, 190);
    g.drawRect(100, 150, 100, 20);
    g.drawOval(115, 155, 10, 10);
    g.drawOval(175, 155, 10, 10);
    g.drawArc(140, 140, 20, 20, 180, -180);


    //off switch
    g.drawLine(160, 150, 182, 133);
    g.drawLine(157, 142, 173, 128);
    g.drawLine(173, 128, 182, 133);


    //Power Supply
    g.drawString(line[1], 50, 420);
    g.drawRect(50, 320, 50, 80);
    g.drawLine(50, 320, 70, 290);
    g.drawLine(100, 320, 120, 290);
    g.drawLine(70, 290, 120, 290);
    g.drawLine(120, 370, 120, 290);
    g.drawLine(120, 370, 100, 400);
    //plus
    g.drawLine(94, 310, 100, 310);
    g.drawLine(97, 307, 97, 313);
    // minus
    g.drawLine(100, 300, 107, 300);
    // pliers
    g.drawRect(70, 305, 5, 10);
    g.drawRect(90, 288, 5, 10);

    //lightbulb
    g.drawString(line[3], 400, 250);
    g.drawRect(400, 200, 20, 20);
    g.drawOval(395, 170, 30, 30);
    // pliers
    g.drawRect(400, 220, 5, 10);
    g.drawRect(415, 220, 5, 10);

    // plus wire to switch
    g.drawLine(72, 305, 120, 160);
    //bulb to switch
    g.drawLine(180, 160, 400, 230);
    //bulb to minus
    g.drawLine(90, 290, 420, 230);
}

public void turnon(Graphics g) {
    // Title
    g.drawString(line[0], 150, 40);

    //Switch
    g.drawString(line[2], 130, 190);
    g.drawRect(100, 150, 100, 20);
    g.drawOval(115, 155, 10, 10);
    g.drawOval(175, 155, 10, 10);
    g.drawArc(140, 140, 20, 20, 180, -180);

    //on switch
    g.drawLine(140, 150, 122, 133);
    g.drawLine(143, 142, 129, 128);
    g.drawLine(122, 133, 129, 128);

    //Power Supply
    g.drawString(line[1], 50, 420);
    g.drawRect(50, 320, 50, 80);
    g.drawLine(50, 320, 70, 290);
    g.drawLine(100, 320, 120, 290);
    g.drawLine(70, 290, 120, 290);
    g.drawLine(120, 370, 120, 290);
    g.drawLine(120, 370, 100, 400);
    //plus
    g.drawLine(94, 310, 100, 310);
    g.drawLine(97, 307, 97, 313);
    // minus
    g.drawLine(100, 300, 107, 300);
    // pliers
    g.drawRect(70, 305, 5, 10);
    g.drawRect(90, 288, 5, 10);

    //lightbulb
    g.drawString(line[3], 400, 250);
    g.drawRect(400, 200, 20, 20);
    g.drawOval(395, 170, 30, 30);
    // pliers
    g.drawRect(400, 220, 5, 10);
    g.drawRect(415, 220, 5, 10);

    // plus wire to switch
    g.drawLine(72, 305, 120, 160);
    //bulb to switch
    g.drawLine(180, 160, 400, 230);
    //bulb to minus
    g.drawLine(90, 290, 420, 230);
}
}

Controller doesn't do much right.

public class Controller {

public void openFile(String filename, Draw drawObject) {
    drawObject.readFile(filename);
}
}

And this is the actionlisterner class

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

public class AllListeners implements ActionListener {

public void actionPerformed(ActionEvent e) {
    Circuit circuitObject = new Circuit();
    Draw drawObject = new Draw();
    String buttonString = e.getActionCommand();

    if (buttonString.equals("Close")) {
        drawObject.setisOn();
        drawObject.repaint();

    } else if (buttonString.equals("Open")) {
        drawObject.setisOff();
        drawObject.repaint();

    } else {
        System.out.println("Unexpected error.");
    }
}
}

Upvotes: 1

Views: 1758

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285430

You've got lots of major problems with this code including:

  • Drawing directly within a JFrame's paint method, something fraught with problems as you risk messing up the JFrame's own complicated painting.
  • Placing program logic within a painting method, a method you don't have full control over when or if it fires, and one that you shouldn't slow down
  • Placing component creation code within a painting method.
  • Trying to add multiple JButtons willy nilly rather than changing the state of an existing component.
  • Creating multiple Circuit objects.
  • Trying to use absolute positioning via setBounds(...) to place a component in a container that uses BorderLayout.

I suggest that you

  • Start over and scrap this code.
  • Draw only in a JPanel's paintComponent method, just as the tutorials will tell you to do.
  • Create your buttons once and only once and add them to your GUI.
  • Get all program logic out of the painting (here paintComponent) method, and all object state changing outside of that method as they are for painting and painting only.
  • Instead the logic should belong to the controller, and which should be notified of the button push.
  • So consider having the button push notify the control what was pushed,
  • the control changes the state of the program (changes variables)
  • and then it calls repaint so that the paintComponent method can use those variables to change its drawing.
  • Also, avoid using setBounds and null layouts if at all possible, and instead use layout managers/borders/nested JPanels to help you place your components.

Upvotes: 3

Related Questions