Quigg15405
Quigg15405

Reputation: 121

java graphics paintComponent

I have three classes - TableApp/Diner/TablePanel. I don't quite understand how the graphics class works. I would need to send a Graphics object reference to my paintComponent from my main method but i'm not sure how to link it together. Any explanation on how would be so helpful!

TableApp Class

import javax.swing.*;
public class TableApp{
  public static void main(String[]args){    
  JFrame frame = new JFrame();
  TablePanel table = new TablePanel();
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setVisible(true);
  frame.setSize(500,500);  //I dont understand how to send my paintComponent a                    reference of a Graphics object
  } 
}

TablePanel Class

import java.awt.*;
import javax.swing.*;

public class TablePanel extends JPanel{

  Diner diner1,diner2,diner3,diner4,diner5,diner6;

  public TablePanel(){
    diner1 = new Diner(50,50,300,1,"Murray",Color.blue);
    diner2 = new Diner(50,50,300,1,"Murray",Color.blue);//will change once program runs
    diner3 = new Diner(50,50,300,1,"Murray",Color.blue);
    diner4 = new Diner(50,50,300,1,"Murray",Color.blue);
    diner5 = new Diner(50,50,300,1,"Murray",Color.blue);
    diner6 = new Diner(50,50,300,1,"Murray",Color.blue);

    setPreferredSize(new Dimension(300,200));
    setBackground(Color.white);


  }
  public void paintComponent(Graphics g){//need call from main
    super.paintComponent(g);
    diner1.draw(g);
    diner2.draw(g);
    diner3.draw(g);
    diner4.draw(g);
    diner5.draw(g);
    diner6.draw(g);
  }

}

Diner Class

    import java.awt.*;
    import javax.swing.*;

    public class Diner{
      private int X,Y,diameter=50,seatNumber;
      private String name;
      private Color colour;

      public Diner(int x,int y,int d,int sN,String n,Color col){//construct
        X=x;
        Y=y;
        name=n;
        diameter=d;
        name=n;
        colour=col;

    }
      public void draw(Graphics g){
            g.setColor(Color.blue);
            g.fillOval(X,Y,diameter,diameter);
        }
}

Upvotes: 1

Views: 8964

Answers (2)

David Kroukamp
David Kroukamp

Reputation: 36423

  • You dont call paintComponent(..) if needs be simply call repaint() which will refresh the container by calling update(..), paint(..), paintComponent(..) etc.

  • In your code you never add the TablePanel table to your JFrame which you should do to make it visible via add(..)

  • Also a diameter of 300 for each Diner and the same x and y co-ordinates of 50x50 would paint all Diners on top of each and the TablePanel with a preferred size of 200x300 would not fit all the table(s) in. So basically the co-ordinates need reworking and/or panel size needs changing.

  • You should not call setSize(..) on JFrame rather implement correct LayoutManager and/or override getPreferredSize() to fit contents of drawings on JPanel (note not good practice to use setPreferredSize(..)) and than call pack() after adding components and before setting JFrame visible.

  • Remember to create and manipulate Swing components on Event Dispatch Thread via SwingUtilities.invokeXXX block.

  • And how about some Graphics2D and RenderingHints to make those circles look perfect :)

  • A further enhancement which I have not shown is using a List to add (via a method call in TablePanel like addDiner(Diner d)) and keep track of all the Diner class instances you add to the TablePanel. This you would simply iterate over the list in paintComponent rather than redundant lines of code.

Here is your code with above mentioned fixes:

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TableApp {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                TablePanel table = new TablePanel();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(table);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

class TablePanel extends JPanel {

    Diner diner1, diner2, diner3, diner4, diner5, diner6;

    public TablePanel() {
        diner1 = new Diner(10, 90, 20, 1, "Murray", Color.blue);
        diner2 = new Diner(70, 30, 20, 1, "Murray", Color.blue);//will change once program runs
        diner3 = new Diner(50, 60, 20, 1, "Murray", Color.blue);
        diner4 = new Diner(100, 90, 20, 1, "Murray", Color.blue);
        diner5 = new Diner(80, 120, 20, 1, "Murray", Color.blue);
        diner6 = new Diner(100, 30, 20, 1, "Murray", Color.blue);
        setBackground(Color.white);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    public void paintComponent(Graphics g) {//need call from main
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        diner1.draw(g2d);
        diner2.draw(g2d);
        diner3.draw(g2d);
        diner4.draw(g2d);
        diner5.draw(g2d);
        diner6.draw(g2d);
    }
}

class Diner {

    private int X, Y, diameter = 50, seatNumber;
    private String name;
    private Color colour;

    public Diner(int x, int y, int d, int sN, String n, Color col) {//construct
        X = x;
        Y = y;
        name = n;
        diameter = d;
        name = n;
        colour = col;

    }

    public void draw(Graphics2D g2d) {
        g2d.setColor(Color.blue);
        g2d.fillOval(X, Y, diameter, diameter);
    }
}

Upvotes: 4

Kakalokia
Kakalokia

Reputation: 3191

You don't pass a Graphics object to paintComponent. This will be done and called by Swing (as someone said) when you add the component to your frame. So what you're not doing in main is the following

frame.add(table)

Once you add the component to your frame, it will be drawn on the frame.

Upvotes: 2

Related Questions