Reputation: 18572
I need to draw a Polygon - by connecting consecutive points and then connecting the last point to the first.
With this goal I tried to use drawPolygon(xPoints, yPoints, nPoints). To my mind it's much more convenience approach to achieve this aim
But the Graphics
class is abstract class and I we can't create instance object and call drawPolygon()
method?
Code:
public void draw() {
Graphics g = null;
int xPoints [] = new int[pointsList.size()];
int yPoints [] = new int[pointsList.size()];
int nPoints = pointsList.size();
for (int i = 0; i < pointsList.size(); i++) {
xPoints [i] = (int) pointsList.get(i).getX();
yPoints [i] = (int) pointsList.get(i).getY();
}
g.drawPolygon(xPoints, yPoints, nPoints);
}
Upvotes: 1
Views: 16266
Reputation: 347184
Painting is controlled by the RepaintManager
. Painting in Swing is done via a series of methods which are called on your behalf when the RepaintManager
decides your component needs to be update (you can, of course, request repaints, but the RepaintManager
will decided when, what and how much).
In order to perform custom painting in Swing, you need to override one of the methods that are called as part of the paint cycle.
It is recommended that you override paintComponent
You can check out
For more details.
In your example, your Graphics
is null
...Graphics g = null;
which isn't going to help...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SimplePloy {
public static void main(String[] args) {
new SimplePloy();
}
public SimplePloy() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PloyPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PloyPane extends JPanel {
private int[] xPoints;
private int[] yPoints;
public PloyPane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
public void invalidate() {
xPoints = null;
yPoints = null;
super.invalidate();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (xPoints == null || yPoints == null) {
int width = getWidth() - 1;
int height = getHeight() - 1;
int halfWidth = width / 2;
int halfHeight = height / 2;
int innerWidth = width / 8;
int innerHeight = height / 8;
xPoints = new int[9];
yPoints = new int[9];
xPoints[0] = halfWidth;
yPoints[0] = 0;
xPoints[1] = halfWidth - innerWidth;
yPoints[1] = halfHeight - innerHeight;
xPoints[2] = 0;
yPoints[2] = halfHeight;
xPoints[3] = halfWidth - innerWidth;
yPoints[3] = halfHeight + innerHeight;
xPoints[4] = halfWidth;
yPoints[4] = height;
xPoints[5] = halfWidth + innerWidth;
yPoints[5] = halfHeight + innerHeight;
xPoints[6] = width;
yPoints[6] = halfHeight;
xPoints[7] = halfWidth + innerWidth;
yPoints[7] = halfHeight - innerHeight;
xPoints[8] = halfWidth;
yPoints[8] = 0;
}
g2d.drawPolygon(xPoints, yPoints, xPoints.length);
g2d.dispose();
}
}
}
Upvotes: 1
Reputation: 2293
I have had the same problem, this was how I circumvented it:
//assuming you are displaying your polygon in a JFrame with a JPanel
public class SomeDrawingFrame extends JPanel{
SomeDrawingFrame(){
}
@Override //JFrame has this method that must be overwritten in order to
display a rendered drawing.
public void paintComponent(Graphics g){
super.paintComponent(g);
Polygon square = new Polygon();
// these points will draw a square
square.addPoint((0, 0)); //use this.getWidth() method if you want to
create based on screen size
square.addPoint((0, 100));
square.addPoint((100, 100));
square.addPoint((100, 0));
int y1Points[] = {0, 0, 100, 100};
g.draw(polygon);
}
}
now just create an instance of this and add it to a JFrame of minimum height and width of 100 each. You can use JFrame's getWidth() method which will return the size of the JFrame and use this to set your points instead (which is better) because then the image will render relative to the size of the frame itself.
Upvotes: 2
Reputation: 310
The reason the developers made Graphics abstract was that a graphics object needs to come from somewhere. For instance a JPanel or JFrame object have a graphics object associated with them since they render viewable areas to the screen. A graphics object is usually assigned with the getGraphics() method. Here is a quick example:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Polygon extends JFrame {
public static void main(String args[]){
Test a = new Test();
a.drawAPolygon();
}
public Polygon(){
setSize(300,300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void drawAPolygon(int[] xPoints, int[] yPoints, int numPoints){
Graphics g = getGraphics();
g.drawPolygon(xPoints, yPoints, numPoints);
}
//@override
public void paint(Graphics g){
super.paint(g);
//could also do painting in here.
}
}
Upvotes: 2