Search code examples
javaswingpaintcomponent

split paintComponent method


I am new to GUI and I am writing a program to display several entries of NameRecord on a graph. I started the whole frame in paintComponent when I only needed to put in one entry.

However, now I need to modify it so that there is storage for multiple entries of NameRecords, which I decided to use ArrayList to store. Then I want to be able to search, clear these entries. But what I have in paintComponent is just too messy.

How can I modify this method so that I have separate classes to store entries and perform other methods? Since I cannot refer to g outside of this class.

@Override
public void paintComponent(Graphics g) {

    super.paintComponent(g);

    w = getWidth();
    h = getHeight();

    //draw horizontal lines
    g.drawLine(0, 20, w, 20);
    g.drawLine(0, h - 20, w, h - 20);

    //draw vertical lines
    for (int i = 1; i < 12; i++) {
        g.drawLine((w / 12) * i, 0, (w / 12) * i, h);
    }
    //draw lable of years
    g.drawString("   1900", 0, 13);
    g.drawString("   1900", 0, h - 7);

    int year = 1900;
    for (int i = 1; i < 12; i++) {
        g.drawString("   " + Integer.toString(year + (i * 10)), (w / 12 * i), 13);
        g.drawString("   " + Integer.toString(year + (i * 10)), (w / 12 * i), h - 7);
    }

    // draw line of rank
    if (nameData != null) {
        nameList.add(nameData);
        for (int i = 0; i < 11; i++) {
            g.drawLine((w / 12 * i), convertValue(nameData.getRank(i)),
                    (w / 12) * (i + 1), convertValue(nameData.getRank(i + 1)));
        }

        for (int i = 0; i < 12; i++) {
            String label = " ";
            label = (nameData.getName() + " " + nameData.getRank(i));
            g.drawString(label, (w / 12 * i), convertValue(nameData.getRank(i)));
        }
    }
}

Also I used another class to do all GUI displays(I am not sure if that is the way to say it, but it calls actionPerformed method). Their connections are kind of confusing to me. I will just put it here as a reference.

 @Override
public void actionPerformed(ActionEvent e) {
    String s = e.getActionCommand();

    if (s.equalsIgnoreCase("graph")) {
        doGraph();
    } else if (s.equalsIgnoreCase("search")) {
        findName(inputField.getText());
    } else if (s.equalsIgnoreCase("clear all")) {
        clear();
        //– remove all names from the NameGraph

    } else if (s.equalsIgnoreCase("clear one")) {

        //remove the name that was added to the NameGraph earliest.
    } else if (s.equalsIgnoreCase("quit")) {
        setVisible(false);
        dispose();
        System.exit(0);
    } else {
        // This is the response to the Enter Key pressed in inputField.
        doGraph();
    }
}

Solution

  • How can I modify this method so that I have separate classes to store entries and perform other methods? Since I cannot refer to g outside of this class.

    You will able to access the Graphics object g by passing it to a method or a method of another class:

    //for example
    class MyGraph{
        public void draw(Graphics g){
            //implements how the graph is drawn, for e.g:
            //g.drawLine(x, y);
        }
    }
    

    In the panel class which is displaying the drawings:

    class DisplayPanel extends JPanel{
    
        private MyGraph;
    
        public DisplayPanel(){
            MyGraph graph = new MyGraph();
        }
    
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            graph.draw(g);            //let the objects draw themselves
        }
    }