java swing : Polygon fill color problem - java

Could any body diagnose the problem I am facing?
As you run the demo you can see the middle part left blank, I need to fill the entire area..
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class FillDemo
{
public static void main(String aths[])
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel pnl = new PolygonDemo();
pnl.setSize(100, 200);
f.getContentPane().add(pnl);
f.setSize(400,280);
f.setLocation(200,200);
f.setVisible(true);
}
}
class PolygonDemo extends JPanel
{
public PolygonDemo()
{
setBackground(Color.white);
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
Polygon p=new Polygon();
p.addPoint(100,0);
p.addPoint(100,100);
p.addPoint(0,100);
p.addPoint(0,0);
p.addPoint(80,0);
p.addPoint(80,20);
p.addPoint(40,20);
p.addPoint(40,40);
p.addPoint(80,40);
p.addPoint(80,100);
p.addPoint(20,100);
p.addPoint(20,80);
p.addPoint(60,80);
p.addPoint(60,60);
p.addPoint(20,60);
p.addPoint(20,0);
p.addPoint(0,0);
g2.setColor(Color.BLACK);
g2.draw(p);
g2.setColor(new Color(120,250,100));
g2.fillPolygon(p);
//g2.fillPolygon(p.xpoints,p.ypoints,p.npoints);
}
}
Many thanks in advance

Your polygon intersects with itself. The fillPolygon method can not clearly decide which point is in and which is out. From the fillPolygon javadoc:
The area inside the polygon is defined using an even-odd fill rule, also known as the alternating rule.
Perhaps you can split your polygon into three single ones.

Draw Rectangle and Fill Color.....
public void paint(Graphics g)
{
int[] xPoints = {100,50,150};
int[] yPoints = {100,200,200};
g.setColor(Color.black);
g.drawPolygon(xPoints, yPoints, 3);
g.setColor(Color.red);
g.fillPolygon(xPoints, yPoints, 3);
}

Related

Java: Program doesn't save old graphics

So, I have been doing Java for a couple of months, and I'm now learing about Graphics. So, I am trying to make a paint kind of thing, where I can just draw with my mouse. Nothing really fancy, just something to get me started. The program just paints a small dot whenever I drag the mouse. It sort of works, except for the fact that it doesn't save my old dots. It just creates a new one! It would be kind if someone could help me with this problem:
Main class:
import javax.swing.JFrame;
public class Test{
public static void main(String args[]){
Ploofer ploof = new Ploofer();
PumpkinPie f = new PumpkinPie(ploof);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1000,1000);
f.setResizable(false);
ploof.setSize(1000,1000);
f.add(ploof);
f.setVisible(true);
}
}
"Ploofer" class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Ploofer extends JPanel{
PumpkinPie pObj = new PumpkinPie(this);
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
this.setBackground(Color.WHITE);
g2d.setColor(new Color(190, 50, 0));
if(pObj.draw==true){
g2d.fillRect(pObj.x, pObj.y, 2, 2);
pObj.draw = false;
}
}
#Override
public void update(Graphics g){
paint(g);
}
//I tried to override update, but it didn't really help
}
"PumpkinPie" class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Ploofer extends JPanel{
PumpkinPie pObj = new PumpkinPie(this);
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
this.setBackground(Color.WHITE);
g2d.setColor(new Color(190, 50, 0));
/* g2d.fillRect(475, 475, 50, 50);
g2d.drawString("^Red^", 484, 540); */
if(pObj.draw==true){
g2d.fillRect(pObj.x, pObj.y, 2, 2);
pObj.draw = false;
}
}
#Override
public void update(Graphics g){
paint(g);
}
//I tried to override update, but it didn't really help
}
It sort of works, except for the fact that it doesn't save my old dots. It just creates a new one!
Check out Custom Painting Approaches for the two common ways to do custom painting:
add objects to paint to an ArrayList and iterate through the list to paint all objects
draw to a BufferedImage and repaint the BufferedImage
In your case I would recommend approach 2.
//I tried to override update, but it didn't really help
Don't override update(). There is no reason to do that. That is an old AWT approach with is not needed in Swing.

Java, JFrame, JComponent, Rectangles

Here are two instances of the exact same code that draws a bunch of rectangles superimposed down a diagonal, except in the second instance there are parentheses around "i^2" for both the x and y values. I believe that the rectangles should begin at (0,0) in both cases, but in the first case they do not begin at the origin. Instead, they begin slightly off from the origin. Why is there a difference when the rectangles are added to the JFrame?
using
javax.swing.JComponent
javax.swing.JFrame
and
java.awt.Rectangle
for(int i=0;i<600;i++){
Rectangle rect1 = new Rectangle(20*i^2, 20*i^2, 50, 100);
g2.draw(rect1);
}
for(int i=0;i<600;i++){
Rectangle rect1 = new Rectangle(20*(i^2), 20*(i^2), 50, 100);
g2.draw(rect1);
}
My code is in two classes. Here is the main class:
import javax.swing.JFrame;
public class MainClass {
public static void main(String[] args){
JFrame window = new JFrame();
window.setSize(600,600);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawingComponent drawing = new DrawingComponent();
window.add(drawing);
window.setVisible(true);
}
}
And here is the code for the DrawingComponent class that makes Rectangles to be added to the JFrame:
import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
public class DrawingComponent extends JComponent{
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
for(int i=0;i<600;i++){
Rectangle rect1 = new Rectangle(20*i^2, 20*i^2, 50, 100);
g2.draw(rect1);
}
}
}
The expression 20*i^2 is not the same as 20*(i^2).
Bitwise XOR operator ^ has lower precedence than multiplication * and so the two expressions will produce different results.

Java - draw a triangle [duplicate]

This question already has answers here:
Triangle Draw Method
(6 answers)
Closed 9 years ago.
Hey I know that it is simple to draw oval/rectangle and fill it using
g.fillOval(30, 40, 20, 20);
but how to draw a triangle? It would be the best if it would have random coordinates.
There are at least two basics ways you can achieve this, based on your needs.
You could use Polygon or you could make use the 2D Graphics Shape API
Which you might choose comes down to your requirements. Polygon requires you to know, in advance the position of the points within 3D space, where the Shape API gives you more freedom to define the shape without caring about the position in advance.
This makes the Shape API more flexible, in that you can define the shape once and simply translate the Graphics context as needed and repaint it.
For example...
Red is a Polygon, green is a Shape, which is translated into position...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TriangleTest {
public static void main(String[] args) {
new TriangleTest();
}
public TriangleTest() {
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private TriangleShape triangleShape;
private Polygon poly;
public TestPane() {
triangleShape = new TriangleShape(
new Point2D.Double(50, 0),
new Point2D.Double(100, 100),
new Point2D.Double(0, 100)
);
poly = new Polygon(
new int[]{50, 100, 0},
new int[]{0, 100, 100},
3);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.fill(poly);
g2d.setColor(Color.GREEN);
g2d.translate(50, 100);
g2d.fill(triangleShape);
g2d.dispose();
}
}
public class TriangleShape extends Path2D.Double {
public TriangleShape(Point2D... points) {
moveTo(points[0].getX(), points[0].getY());
lineTo(points[1].getX(), points[1].getY());
lineTo(points[2].getX(), points[2].getY());
closePath();
}
}
}
Using the legacy Graphics class, this would be done by using the legacy method
drawPolygon(int[] x, int[] y, int pointCount).
The newer class Graphics2D supports a much nicer implementation using Path2Ds. You will need either the draw(Shape) or fill(Shape) method. Given the fact that almost everywhere in Java a Graphics object is actually a Graphics2D object, you can cast it so, that is the way to go, IMHO.
Graphics g = ...;
Graphics2D g2d = (Graphics2D) g;
Path2D.Double triangle = new Path2D.Double();
triangle.moveTo(x1, y1);
triangle.pathTo(x2, y2);
triangle.pathTo(x3, y3);
triangle.closePath();
g2d.fill(triangle);

Excluding areas while coloring in Java

I have a graphics object and I want to color all the area except some rectangles. For e.g.
I want to color all area except these black areas. Can I do that? There can be many rectangles in the image.
I recommend you to fill all area with White color, and then draw Black rectangles on that, because it's simplier that draw figure with holes. For example like next:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DrawExample extends JPanel{
List<Rectangle> rctangles = new ArrayList<>();
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawExample drawExample = new DrawExample();
drawExample.addRect(new Rectangle(20,20,25,25));
drawExample.addRect(new Rectangle(50,50,25,25));
frame.add(drawExample);
frame.setSize(200,200);
frame.setVisible(true);
}
private void addRect(Rectangle rectangle) {
rctangles.add(rectangle);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
for(Rectangle r : rctangles){
g.fillRect(r.x, r.y, r.width,r.height);
}
}
}

How can I resize and paintComponent inside a frame

Write a program that fills the window with a larrge ellipse. The ellipse shoud touch the window boundaries, even if the window is resized.
I have the following code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
public class EllipseComponent extends JComponent {
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double ellipse = new Ellipse2D.Double(0,0,150,200);
g2.draw(ellipse);
g2.setColor(Color.red);
g2.fill(ellipse);
}
}
And the main class:
import javax.swing.JFrame;
public class EllipseViewer {
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(150, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
EllipseComponent component = new EllipseComponent();
frame.add(component);
frame.setVisible(true);
}
}
in your EllipseComponent you do:
Ellipse2D.Double ellipse = new Ellipse2D.Double(0,0,getWidth(),getHeight());
I'd also recommend the changes given by Hovercraft Full Of Eels. In this simple case it might not be an issue but as the paintComponent method grows in complexity you realy want as little as possible to be computed in the paintComponent method.
Do not resize components within paintComponent. In fact, do not create objects or do any program logic within this method. The method needs to be lean, fast as possible, do drawing, and that's it. You must understand that you do not have complete control over when or even if this method is called, and you certainly don't want to add code to it unnecessarily that may slow it down.
You should create your ellipse in the class's constructor. To resize it according to the JComponent's size and on change of size, use a ComponentListener.:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
public class EllipseComponent extends JComponent {
Ellipse2D ellipse = null;
public EllipseComponent {
ellipse = new Ellipse2D.Double(0,0,150,200);
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// set the size of your ellipse here
// based on the component's width and height
}
});
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.draw(ellipse);
g2.setColor(Color.red);
g2.fill(ellipse);
}
}
Caveat: code not run nor tested

Categories