Reputation: 121
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!
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
}
}
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);
}
}
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
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 Diner
s 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:
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
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