I'm trying to fill each circle with a colour. The paintComponent method is supposed to create the general outline of a traffic light.
Then the other methods are supposed to fill each circle with a different color, depending on what color the traffic light is going to be. I get the error, that it cant find symbol( e.g
TrafficLight.java:56: error: cannot find symbol
g2.fill(circle3);
I didnt think I had to pass the circle variables into the other methods, if they were in the same class. I tried adding the circle variables and then i get identifier expected. Pretty sure there's something about the passing of variables that im not getting, but any help would be appreciated
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class TrafficLight extends JComponent
{
public void paintComponent(Graphics g)
{
Graphics2D g2= (Graphics2D) g;
Rectangle box= new Rectangle(100,800,200,700);
g2.setPaint(Color.BLACK);
g2.fill(box);
g2.draw(box);
Ellipse2D.Double circle1=new Ellipse2D.Double(200,200,200,200);
g2.draw(circle1);
Ellipse2D.Double circle2=new Ellipse2D.Double(200,200,200,400);
g2.draw(circle2);
Ellipse2D.Double circle3=new Ellipse2D.Double(200,200,200,600);
g2.draw(circle3);
}
public void drawRed(Graphics g)
{
Graphics2D g2=(Grpahics2D) g;
g2.setPaint(Color.RED);
g2.fill(circle1);
g2.setPaint(Color.BLACK);
g2.fill(circle2);
g2.fill(circle3);
}
public void drawGreen(Graphics g)
{
Graphics2D g2= (Graphics2D) g;
g2.setPaint(Color.GREEN);
g2.fill(circle3);
g2.setPaint(Color.BLACK);
g2.fill(circle2);
g2.fill(circle1);
}
public void drawYellow(Graphics g)
{
Graphics2D g2= (Graphics2D) g;
g2.setPaint(Color.YELLOW);
g2.fill(circle2);
g2.setPaint(Color.BLACK);
g2.fill(circle1);
g2.fill(circle3);
}
}
The entire code is missing.
But the general solution is to have the paintComponent method do all.
So have a state red/green/yellow.
public class TrafficLight extends JComponent {
public enum Light { RED, GREEN, YELLOW, BLACK }
private Light light = Light.BLACK;
public void setLight(Light light) {
this.light = light;
repaint(50L); // Repaint almost immediately.
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
...
// Draw red bulb
g2.setPaint(light == Light.RED ? Color.RED : Color.BLACK);
...
// Draw yellow bulb
g2.setPaint(light == Light.YELLOW ? Color.YELLOW : Color.BLACK);
...
// Draw green bulb
g2.setPaint(light == Light.GREEN ? Color.GREEN : Color.BLACK);
Switching the light then alters the state and causes a repaint. There are some repaint methods.
Instead of the enum one might use Color light;, but that is not so clear.
Also consider an enum value BLACK, for semaphores without electricity.
To handle automatic timed switching, one might use a swing Timer.
Related
I have an ArrayList of Shapes (Rectangles and Ovals) and I want to paint these shapes. How do I fill them with color in the for loop?
My ArrayList is composed of both Rectangles and Ovals. If I do fillRect(color), it paints all shapes as Rectangles, and if I do fillOval(color), it paints all shapes as Ovals. How can I fill the Ovals and Rectangles appropriately? The code below only does the outlines.
private ArrayList<Shape> shapes = new ArrayList<Shape>();
private Shape currentShape; // the shape being drawn (either Rectangle or Oval)
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(Shape s : shapes) {
Graphics2D g2d = (Graphics2D) g.create();
s.paint(g2d);
}
}
Graphics2D.fill(Shape) will do.
private List<Shape> shapes = new ArrayList<>();
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
for (Shape shape : shapes) {
g2d.fill(shape);
}
}
No g.create. The fact that every paintComponent parameter is actually a Graphics2D is historically founded: they replaced Graphics by a more exhaustive Graphics2D, but for backward compatibility kept Graphics.
How do I fill them with color in the for loop?
You need to store the Color information with the Shape. So you need to create a custom object with two properties: "shape" and "color". Then you can set the Graphics Color before you paint the Shape.
See Custom Painting Approaches for a working example of this approach.
I am drawing two stars using:
public void draw(Graphics2D g2) {
g2.drawPolygon(xCoordOfStar, yCoordOfStar, POINTS);
g2.setStroke(new BasicStroke(5));
}
and:
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Star star1 = new Star(100,200,300);
Star star2 = new Star(200,200,300);
star1.draw(g2);
star2.draw(g2);
}
In the other class.
For some reason unknown to me, only the bigger star (star2) gets a thicker border, while star1 does not get any border. What am I doing wrong?
It's an ordering issue. Your second Polygon gets a border because your first Polygon called the g2.setStroke(new BasicStroke(5)); Comment out the first star code, the second star now also loses its border.
To fix it, you just need to rearrange the methods:
public void draw(Graphics2D g2) {
g2.setStroke(new BasicStroke(5));
g2.drawPolygon(xCoordOfStar, yCoordOfStar, POINTS);
}
I have this much of the code for the shape and fill. I want the shape and fill to combine into one shape which will keep iits color and stroke, but could be transformed.
public class ShapeGraphics extends Applet {
public void init() {
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(4));
g2d.setColor(Color.BLACK);
Rectangle rect2= new Rectangle(47, 46, 127, 128);
Rectangle rect3=new Rectangle(35,72,34,68);
Color c1=new Color(255,0,0),c2=new Color(50,208,7),c3=new Color(40,166,243)
,c4=new Color(254,174,1);
g2d.draw(rect2);
//RED
g2d.setColor(c1);
g2d.fill(rect3);
//GREEN
g2d.setColor(c2);
//BLUE
g2d.setColor(c3);
g2d.fill(rect2);
/***********************************************************************************/
//START OF LAYER 2
//BLACK LINE!
g2d.setColor(Color.BLACK);
g2d.draw(rect3);
//RED
g2d.setColor(c1);
g2d.fill(rect3);
//Orange
g2d.setColor(c4);
}}
The output is a blue square with a red rectangle. Thanks in Advance
In my paintComponent, I have drawRect, which draws a single rectangle. However, I want to make the outline of the rectangle thicker but I don't know how. So I thought of making another rectangle inside the existing one. I tried putting another drawRect but the rectangle isn't in the center.
Thanks for those who'll help!
g2d.setStroke(new BasicStroke(6));
The argument passed to the paintComponent(Graphics) method of a Swing component should actually be a Graphics2D instance. It can be cast to one.
See this example in which 3 strokes are layered.
import javax.swing.*;
import java.awt.*;
class StrokeIt {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
StrokePanel sp = new StrokePanel();
sp.setPreferredSize(new Dimension(400,100));
sp.setBackground(Color.BLUE);
JOptionPane.showMessageDialog(null, sp);
}
});
}
}
class StrokePanel extends JPanel {
int pad = 12;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(10));
g2d.drawRect( 0+pad, 0+pad,
getWidth()-(2*pad), getHeight()-(2*pad) );
g2d.setColor(Color.YELLOW);
g2d.setStroke(new BasicStroke(6));
g2d.drawRect( 0+pad, 0+pad,
getWidth()-(2*pad), getHeight()-(2*pad) );
g2d.setColor(Color.ORANGE);
g2d.setStroke(new BasicStroke(2));
g2d.drawRect( 0+pad, 0+pad,
getWidth()-(2*pad), getHeight()-(2*pad) );
}
}
I have asked a similar question a while ago here, but didn't get an answer. The original question was about changing the color of a shape after clicking on it. But I am puzzled on how to access the shape at all after it is drawn.
This is my paintComponent method
#Override
protected void paintComponent(Graphics graph) {
super.paintComponent(graph);
Graphics2D g = (Graphics2D) graph;
// smooth graphics
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// moving to the middle of the panel
g.translate(this.getWidth()/2, this.getHeight()/2);
// painting colored arcs
for(int i = 0; i < 4; i++) {
g.setColor(dimColors[i]);
g.fill(arcs[i]);
}
// painting borders
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(5F));
g.drawLine(-98, 0, 98, 0);
g.drawLine(0, -98, 0, 98);
g.draw(circle);
// painting central white circle
g.setColor(Color.WHITE);
g.fill(smallCircle);
g.setColor(Color.BLACK);
g.draw(smallCircle);
}
the arcs[] array contains a bunch of Arc2D's that are drawn on the panel. My question is now, if I want to change the color of, for example arcs[0], how do I do that?
Thanks!
EDIT: I now have this MouseAdapter event
private class MyMouseAdapter extends MouseAdapter {
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Component c = getComponentAt(p);
Graphics g = c.getGraphics();
dimColors[1] = Color.RED;
paintComponent(g);
}
}
And it works, it changes the color of arc[1] because arcs[1] has dimColors[1] set as color when drawing it.
However, I still can't figure out how to check wether the right arc was clicked. Right now you just click anywhere on the graphics panel and it changes the color of that specific arc
This doesn't answer your earlier question, however it does answer your question of click detection. To do this it is best to use Graphics2D because it is a lot easier to write than most other options. Here is an example:
public class GraphicsPanel extends JPanel implements MouseListener
{
private Rectangle2D rect;
First we create our Graphics2D rectangle rect.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)(g);
g2d.setColor(Color.GREEN);
rect = new Rectangle2D.Double(70, 70, 100, 100);
g2d.fill(rect);
this.addMouseListener(this);
}
And then we override the paintComponent method and create our new Rectangle2D.Double object.
We then fill the rectangle with g2d.fill() and then add a mouse listener to the JPanel.
public void mousePressed(MouseEvent e)
{
if(rect.contains(e.getX(), e.getY()))
System.out.println("Rectangle clicked");
}
}
Finally, we need to see if that rectangle contains the point where the user clicked. To do this, simply see if the rectangle we created contains the user's click location by using the Rectangle2D.double's contains(int x, int y) method. That's it!
if I want to change the color of, for example arcs[0], how do I do that?
A line (or whatever) only exists as a bunch of pixels that were painted in the original color. To change its color you must change the current color and draw it again.