graphing data from a website - java

I am creating a program where I plot the maximum daily temperature for a specific city using data retrieved directly from the National Weather Service web site. I have the data, but the program errors when I try to create the actual graph. My error says that I need a return type but if you look a my code, I have one. Its in OOP format so the code I will show you is part of the implementation class. Can someone tell me how to fix my error?
My error:
invalid method declaration; return type required
My Code:
public class createGraph
{
Picture canvas = null;
Graphics g = null;
Graphics2D g2 = null;
DrawingGraph(int length, int height, Color color)
{
canvas = new Picture(length, height);
canvas.setAllPixelsToAColor(color);
g = canvas.getGraphics();
g2 = (Graphics2D)g;
g2.setColor(color);
}
public void drawARectangle(Color color, int x1, int y1, int width, int height)
{
g2.setColor(color);
g2.drawRect(x1, y1, width, height);
}
public Picture getGraph()
{
return canvas;
}
g.drawString("Maximum Temperature Readings", 196, 65);
g.drawString("Pensacola, FL - August, 2009", 205, 80);
int xPos = 97;
for(int day = 1; day <= 31; day++)
{
xPos = xPos + 13;
g.drawLine(xPos, 500, xPos, 510);
}
for(int yPos = 100; yPos <= 500; yPos +=40)
{
g.drawLine(93,yPos, 100, yPos);
}
g.drawString("100", 70, 105);
g.drawString("90", 75, 145);
g.drawString("80", 75, 185);
g.drawString("70", 75, 225);
}
The final graph should end up looking like this:

This code here:
DrawingGraph(int length, int height, Color color)
{
canvas = new Picture(length, height);
canvas.setAllPixelsToAColor(color);
g = canvas.getGraphics();
g2 = (Graphics2D)g;
g2.setColor(color);
}
Is that supposed to be a method or the constructor? If it's a normal method, you need void, or if it's the constructor, it should be the same name as the class.
You also have lots of code which is not in a method at all.

DrawingGraph isn't an function nor a Constructor, if it's meant to be an function, it needs am return-Type, if it should be a Constructor, it must have the same name as the class.
Also, the last part of your class, after getGraph(), must be in a function, but is located directly in the class body.
Just declare an new Function and move it in it an call it.

the class name starts with a lowerCase.
Are you shure that you did't swap "lowerCase" and "DrawingGraph" ?

Related

How could I make my Snowmans arms wave using Graphics 2D?

So I am currently creating a drawing that creates a Snowman, as well as some other objects in the background. I got the drawing part down, it looks just as it should, but I wanted to add a little bit of movement within it. I used Graphics2D to draw all my shapes, lines, ellipses, etc., but I'm not sure how/if I can make the Snowmans arms wave back and forth with the drawLine method.
I provided the code for the entire Snowman here. It's very simple, as I said it just uses Graphics2D to draw everything. The arm1 and arm2 are near the bottom.
public class Snowman {
private int x;
private int y;
private int width;
private int height;
public Snowman(int x, int y, int width, int height) {
this.x=x;
this.y=y;
this.width=width;
this.height=height;
}
public void draw(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// the body of the snowman
g2.setColor(Color.WHITE);
g2.fillOval(x+125, y+40, 200, 200);
g2.fillOval(x+75, y+140, 300, 300);
g2.fillOval(x+25, y+290, 400, 400);
// the buttons
g2.setColor(Color.BLACK);
g2.fillOval(x+210, y+210, 40, 40);
g2.fillOval(x+210, y+270, 40, 40);
g2.fillOval(x+210, y+330, 40, 40);
// the eyes and mouth
g2.fillOval(x+190, y+98, 20, 20);
g2.fillOval(x+245, y+98, 20, 20);
g2.drawArc(x+180, y+120, 100, 50, 200, 140);
// arm1
g2.drawLine(x+75, y+270, x, y+90);
//arm2
g2.drawLine(x+375, y+270, x+450, y+90);
// the hat
g2.setColor(Color.BLACK);
g2.fillRect(x+177, y+40, 100, 30);
g2.fillRect(x+202, y, 50, 50);
}
}
Is there a way I can implement something to make them move? Or would I have to draw these another way?
you can add a method that adjusts the coordinates of the hand, and this method might contain some if statement so say if the hand reached specific x it will subtract from x to go to the other direction. And then call this method inside the draw function

Using for loop to make multiple drawLine shapes [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am making a star using a draw line. I want to run a for loop to expand a star into multiple stars in a grid-like pattern. I am fairly new to java and could use some help with my code. The gride pattern that I would like the stars to open up too isn't too specific as far as columns x rows go. even making 6 stars or 9 stars is fine, as long as they are in a grid-like pattern.
So far, I have the star drawn with drawLine. At one point I got two stars but they were to close to each other. When I run the code it looks like I have a whole bunch of stars sort of staggered on top of each other and being able to get two stars on Star Field, I would like to get more in such 5x6 pattern or something close. I believe I might be having a hard time computing the math in the for loops to get this to happen.
Should I run, multiple nested for loops or is there a way to do this with using a minimal amount of for loops?
public static void drawFlag(int stars, int stripes, java.awt.Graphics
g, int x, int y, int width, int height) {
// Sets backround rectangle color to white
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
// Draw filled red rectangles *stripes*
int stripeHeight = height/stripes;
g.setColor(Color.RED);
int lastStripeDrawnY = 0;
// For loop runs red stripes
for (int i = y; i < y + height - 2*stripeHeight; i = i + 2*stripeHeight)
{
g.fillRect(x, i, width, stripeHeight);
lastStripeDrawnY = i;
}
// expands strips across the rectangle
int lastStripeY = lastStripeDrawnY+2*stripeHeight;
int lastStripeHeight = y + height - lastStripeY;
if (stripes%2 != 0) {
g.fillRect(x, lastStripeY, width, lastStripeHeight);
}
int stars1 = 15;
for (int cols = 1; cols <= stars1; cols++) {
int rows = stars1/cols;
if (cols > rows && cols <2*rows && cols*rows == stars1) {
}
}
// Draws the starField
int numberOfRedStripes = (int)Math.ceil(stripes/2.0);
int starFieldHeight = numberOfRedStripes*stripeHeight;
int starFieldWidth = starFieldHeight*width/height;
g.setColor(Color.BLUE);
g.fillRect(x, y, starFieldWidth, starFieldHeight);
for (int x1 = 0; x1+100 <+ starFieldWidth-5; x1++) {
if(x1/5*4 == stars) {
drawStar(g,x1,y,50);
for(int y1 = 0; y1 <=starFieldHeight-5;y1++) {
if(y1/4*2 == stars) {
drawStar(g,x,y1,50);
}
}
}
}
}
// drawLine the star
public static void drawStar(java.awt.Graphics g, int x, int y, int size)
{
g.setColor(Color.WHITE);
g.drawLine(x+size/2, y+size/6, x+4*size/5, y+5*size/6);
g.drawLine(x+4*size/5,y+5*size/6, x+size/6, y+2*size/5);
g.drawLine(x+size/6, y+2*size/5, x+5*size/6, y+2*size/5);
g.drawLine(x+5*size/6, y+2*size/5, x+size/5, y+5*size/6);
g.drawLine(x+size/5, y+5*size/6, x+size/2, y+size/6);
}
}
Expand one star into a checkered grid-like pattern.
There are a number of ways you can approach this problem, you can, as you've started, simply try and build each star individually based on the required x/y position.
You could make a single star that was always at 0x0 and translate the Graphics context to the desire x/y position
Or, you could take advantage of the Shape API.
This allows you to define a self contained object which describes the shape you are trying to create.
public class StarShape extends Path2D.Double {
public StarShape(double size) {
double mid = size / 2d;
moveTo(mid, 0);
lineTo((size * 0.6d), (size * 0.4d));
lineTo(size, (size * 0.4d));
lineTo((size * 0.72d), (size * 0.58d));
lineTo((size * 0.85d), size);
lineTo((size * 0.5d), (size * 0.72d));
lineTo((size * 0.2), size);
lineTo((size * 0.325d), (size * 0.58d));
lineTo(0, (size * 0.4d));
lineTo((size * 0.4d), (size * 0.4d));
closePath();
}
}
There are lots of side benefits to this, but the immediate benefit is that it's "paintable". You can pass an instance of it directly to Graphics2D and have it painted and/or filled based on your needs.
Now, with that in hand, you can do something like...
public class TestPane extends JPanel {
private StarShape star;
private double starSize = 10;;
public TestPane() {
star = new StarShape(starSize);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double y = 0;
for (int yIndex = 0; yIndex < getHeight() / starSize; yIndex++) {
double x = 0;
for (int xIndex = 0; xIndex < getWidth() / starSize; xIndex++) {
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
PathIterator path = star.getPathIterator(at);
GeneralPath p = new GeneralPath();
p.append(path, true);
g2d.fill(p);
x += starSize;
}
y += starSize;
}
g2d.dispose();
}
}
The reason I'd prefer this method, is it doesn't affect the origin of the original starShape. You could also use the technique to cache the results, so you're not repeatedly doing it in the paintComponent method.
You could also do something like...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double y = 0;
for (int yIndex = 0; yIndex < getHeight() / starSize; yIndex++) {
double x = 0;
for (int xIndex = 0; xIndex < getWidth() / starSize; xIndex++) {
Graphics2D starg = (Graphics2D) g2d.create();
starg.translate(x, y);
starg.fill(star);
starg.dispose();
x += starSize;
}
y += starSize;
}
g2d.dispose();
}
Which changes the origin of the Graphics context instead or something like...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double xCount = getWidth() / starSize;
for (int yIndex = 0; yIndex < getHeight() / starSize; yIndex++) {
for (int xIndex = 0; xIndex < getWidth() / starSize; xIndex++) {
g2d.fill(star);
star.transform(AffineTransform.getTranslateInstance(starSize, 0));
}
star.transform(AffineTransform.getTranslateInstance(-(starSize) * xCount, starSize));
}
g2d.dispose();
}
which changes the origin of the star itself.
Personally, I prefer not to affect the original and instead simply change the context in how it's painted, but which method you use will come down to your needs.
Okay, that might seem like a lot of work for little gain, but the Shapes API is extremely powerful. Because it's point based (instead of pixel based), it can be more easily resized, without generating pixilation. It's very simple to rotate, through the use of AffineTransform and makes for a much simpler point of re-use.
Want to make the stars bigger? Simply change starStar, for example...
private double starSize = 50;
and the API takes care of the rest...
I used your drawStar() function and built this StarPanel. Try it and see if it gives you some hints for what you are trying to achieve.
Note that I removed g.setColor(Color.WHITE); line from your drawStar() function. We need to be careful when we set color of Graphics object. In many cases, this is the reason why we don't see what we draw.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
public class StarPanel extends JPanel
{
private int xStarting;
private int yStarting;
private int numberOfRows;
private int numberOfColumns;
private int xDisplacement;
private int yDisplacement;
public StarPanel(int xStarting, int yStarting,
int numberOfRows, int numberOfColumns,
int xDisplacement, int yDisplacement)
{
this.xStarting = xStarting;
this.yStarting = yStarting;
this.numberOfRows = numberOfRows;
this.numberOfColumns = numberOfColumns;
this.xDisplacement = xDisplacement;
this.yDisplacement = yDisplacement;
}
public static void main(String[] args)
{
StarPanel starPanel = new StarPanel(50, 50, 5, 6, 75, 75);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(starPanel);
frame.setBounds(300, 200, 500, 600);
frame.setVisible(true);
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
for (int row = 0; row < numberOfRows; row++) {
for (int column = 0; column < numberOfColumns; column++) {
drawStar(g, xStarting + (row * xDisplacement), yStarting + (column * yDisplacement), 50);
}
}
}
// drawLine the star
public static void drawStar(java.awt.Graphics g, int x, int y, int size)
{
g.drawLine(x+size/2, y+size/6, x+4*size/5, y+5*size/6);
g.drawLine(x+4*size/5,y+5*size/6, x+size/6, y+2*size/5);
g.drawLine(x+size/6, y+2*size/5, x+5*size/6, y+2*size/5);
g.drawLine(x+5*size/6, y+2*size/5, x+size/5, y+5*size/6);
g.drawLine(x+size/5, y+5*size/6, x+size/2, y+size/6);
}
}

java static map doesn't update in other class

Hi there and thanks for reading,
I have a Map initialized as follows:
static HashMap<Point, Tile> map = new HashMap<Point, Tile>();
a Tile is a small class that holds an image and a function called addFloor(int tileCode):
class Tile {
BufferedImage img;
int imgHeight, imgWidth;
public Tile(BufferedImage img) {
this.img = img;
imgHeight = img.getHeight();
imgWidth = img.getWidth();
}
public Tile addFloor(int tileCode) {
BufferedImage newImg = Helper.joinBufferedImageFloor(this.img, Map.buildings.get(tileCode).img);
Tile newTile = new Tile(newImg);
return newTile;
}
}
The addFloor(int tileCode) function just puts an image obtained by another map via the tileCode as key (Map is just another class that holds the map of Tiles and maps of asset images, and also some unimportant functions for now) on top of the Tile image (this.img) with an offset.
(Are you still with me or do i need to give more info?)
and now:
Tile tileDebug = Map.map.get(new Point(10, 10));
Map.map.replace(new Point(10, 10), Map.map.get(new Point(10, 10)).addFloor(tileCode)); //I've also tried map.put()
tileDebug = Map.map.get(new Point(10, 10)); //MARK 1
panel.repaint();
I checked via eclipse debugger and I checked the addFloor(int tileCode) function seperated:
-the addFloor(int tileCode) function works perfectly. It creates a new image and returns a completely new Tile with the correct image.
-using the debugger I saw that the Tile updated, it changed its image and has another hash now (same as returned by addFloor(int tileCode)).
-Currently the paintComponent(Graphics g) function has just one call to drawMap(Graphics2D g2d) which draws Tile by Tile.
-Since the map.replace() call the map hasn't been edited.
private void drawMap(Graphics2D g2d) {
if (map != null) {
for (int y = 1; y <= 100; y++) {
for (int x = 1; x <= 100; x++) {
Tile currentTile = Map.map.get(new Point(x, y)); //MARK 2
if (x == 10 && y == 10) {
//This line is just so I can add a breakpoint to debug the tile currentTile
System.out.println("");
} //Unimportant from here, just positioning and drawing, that works perfectly
int dx = 350, dy = 0;
dx += Main.viewX;
dy += Main.viewY;
int posX, posY;
posX = (int) ((x * 64 + y * -64));
posY = (int) ((x * 32 + y * 32));
posX -= currentTile.imgWidth;
posY -= currentTile.imgHeight;
g2d.drawImage(currentTile.img, posX + dx, posY + dy, this);
}
}
}
}
The problem is that the drawn Tile isn't the old Tile, it isn't the Tile that got returned by addFloor(int tileCode). The drawn Tile is a new one, with its own hash and image. The image that is drawn is the second image passed to joinBufferedImageFloor(BufferedImage img1, BufferedImage img2) (the one obtained via the tileCode in addFloor(int tileCode).
I followed my entire program from //MARK 1 to //MARK 2, but the map never got explicitly edited but the return value of
Map.map.get(new Point(10, 10))
changed from the correct Tile (MARK 1) to the third Tile (MARK 2)
Is it because the Map is static? (Note: Only 2 Threads explicitly edit the Map, the Main Thread and a KeyListener Thread, but in this use case this Thread wasn't involved)
Whats wrong here?
Am I getting something wrong about Java Maps?
Any help appreciated thanks in advance
Edit 1min after posting it:
I think I described it a bit confusing here and there so please ask any question that might be unanswered in this description.
On wish I can also provide you with the full Project setup etc...
Edit few Hours after:
Edited the Question according to the how-to-ask section of StackOverflow
Edit for anyone interested the joinBufferedImageFloor(BufferdImage img1, BufferedImage img2) function:
public static BufferedImage joinBufferedImageFloor(BufferedImage img1, BufferedImage img2) {
int offsetX = 16;
int offsetY = -32;
int width = img1.getWidth();
int height = img1.getHeight() - offsetY;
BufferedImage newImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = newImage.createGraphics();
Color oldColor = g2.getColor();
g2.setColor(Color.BLACK);
g2.fillRect(0, 0, width, height);
g2.setColor(oldColor);
g2.drawImage(img1, null, 0, -offsetY);
g2.drawImage(img2, null, offsetX, 0);
g2.dispose();
return newImage;
}

How can I rotate an onscreen component in Java?

import javax.swing.*;
import java.awt.*;
public class JFrameAnimationTest extends JFrame {
public static void main(String[] args) throws Exception{
AnimationPanel animation = new AnimationPanel();
JFrameAnimationTest frame = new JFrameAnimationTest();
frame.setSize(600, 480);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(animation);
frame.setVisible(true);
for(int i = 0; i < 100; i++) {
animation.incX(1);
//animation.incY(1);
animation.repaint();
Thread.sleep(10);
}
}
}
class AnimationPanel extends JPanel {
int x = 10;
int y = 10;
public AnimationPanel() {
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawRect(x, y, 20, 20);
g.fillRect(x, y, 20, 20);
}
protected void incX(int X) {
x += X;
}
protected void incY(int Y) {
y += Y;
}
}
So anyways theres my code. It probably looks a bit jumbled as I am not used to stackoverflow just yet so I apologize.
Here's my question: This program makes this small rectangle slowly move to the right; how can I add rotation to the rectangles movement during that time period?
Note: I haven't actually compiled this code, but you get the gist.
public void paintComponent( Graphics g )
{
super.paintComponent( g );
Graphics2D g2d = (Graphics2D) g;
// The 20x20 rectangle that you want to draw
Rectangle2D rect = new Rectangle2D.Double( 0, 0, 20, 20 );
// This transform is used to modify the rectangle (an affine
// transform is a way to do operations like translations, rotations,
// scalings, etc...)
AffineTransform transform = new AffineTransform();
// 3rd operation performed: translate the rectangle to the desired
// x and y position
transform.translate( x + 10, y + 10 );
// 2nd operation performed: rotate the rectangle around the origin
transform.rotate( rotation );
// 1st operation performed: translate the rectangle such that it is
// centered on the origin
transform.translate( -10, -10 );
// Apply the affine transform
Shape s = transform.createTransformedShape( rect );
// Fill the shape with the current paint
g2d.fill( s );
// Stroke the edge of the shape with the current paint
g2d.draw( s );
}
Also note that you should really be using something like a javax.swing.Timer when you modify x, y, and rotation and when you call repaint(). That way all of it happens on the event dispatch thread.

JPanel repaint from another class

I have a JPanel which displays an image. In a separate class, I'm reading from an xml file points. I am firstly creating an arraylist of triangles from these points. However I need to show the triangles on the image, i.e. draw them on! (yes this should be simple). But as these points and triangles are created in another class, I do not seem to be able to draw them on the already-displayed image within the GUI class. I have tried creating a ArrayList in the JPanel itself, which I update and then want to repaint, although it will not let me do this as shown below:
Class
triangles = clips.getTriangles();
tempPanel.setTriangles(triangles){
JPanel
public void settriangles(ArrayList<Point[]> t){
triangles = t;
repaint();
}
My only other idea is for the JPanel to have a listener waiting for when triangles are returned, updating the field and hence then repainting.
Any ideas?
Thanks
Edit: Code for Drawing
public void settriangles(ArrayList<Point[]> t){
triangles = t;
repaint();
}
public void paintComponent(Graphics g) {
System.out.println("in paint component");
if (g != null) {
Graphics2D graphics = (Graphics2D) g;
try {
Rectangle back_rect = new Rectangle(0, 0, getWidth(),
getHeight());
graphics.setColor(GuiComponentGenerator.GUI_BACKGROUND_COLOUR);
graphics.fill(back_rect);
if (image != null) {
int width = Math.round(image.getWidth() * magnification);
int height = Math.round(image.getHeight() * magnification);
Rectangle image_rect = new Rectangle(offset.x, offset.y,
width, height);
graphics.setColor(Color.BLACK);
graphics.draw(image_rect);
graphics.drawImage(image, offset.x, offset.y, width,
height, null);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for(int pos = 0; pos < triangles.size(); pos++){
Point[] current = triangles.get(pos);
ArrayList<Point> current_triangle = new ArrayList<Point>();
current_triangle.add(current[0]);
current_triangle.add(current[1]);
current_triangle.add(current[2]);
drawRegion(graphics, current_triangle);
}
}
}
finally {
graphics.dispose();
}
}
private void drawRegion(Graphics2D graphics, ArrayList<Point> points) {
graphics.setColor(trans_grey);
Area area = getArea(points);
graphics.fill(area);
graphics.setStroke(new BasicStroke(2));
graphics.setColor(Color.BLACK);
graphics.draw(area);
}
private Area getArea(ArrayList<Point> points) {
Area area = new Area(getPath(points, true));
return area;
}
private GeneralPath getPath(ArrayList<Point> points, boolean close_path) {
GeneralPath path = new GeneralPath();
Point current_screen_point = calculateScreenPoint(points.get(0));
path.moveTo(current_screen_point.x, current_screen_point.y);
for (int point_num = 1; point_num < points.size(); point_num++) {
current_screen_point = calculateScreenPoint(points.get(point_num));
path.lineTo(current_screen_point.x, current_screen_point.y);
}
if (close_path)
path.closePath();
return path;
}
public Point calculateScreenPoint(Point image_point) {
float h_proportion = (float) image_point.x / (float) image.getWidth();
float v_proportion = (float) image_point.y / (float) image.getHeight();
float image_width_in_panel = (float) image.getWidth() * magnification;
float image_height_in_panel = (float) image.getHeight() * magnification;
Point on_screen_point = new Point(0, 0);
on_screen_point.x = offset.x
+ Math.round(h_proportion * image_width_in_panel);
on_screen_point.y = offset.y
+ Math.round(v_proportion * image_height_in_panel);
return on_screen_point;
}
Your paintComponent leaves a little to be desired ;)
Firstly, you should never get a null graphics unless the paint method has been called in correctly, which in case they deserve for it to fail.
You should try and use Graphics.create to create a copy of the incoming Graphics context. This allows you to mess with the Graphics properties (such as transforms etc) without adversly effecting the original
I don't know what the image is all about, but basically, if its null, your triangles will never paint (don't know if this is what you want or not).
I don't know what the offset relates to, but just in case, the 0x0 point is always the top, left corner of your component.
public void paintComponent(Graphics g) {
// This is important, you will to have a very good reason not to call this
super.paintComponent(g);
System.out.println("in paint component");
// Should never need this. You should never call the paintComponent
// directly.
// if (g != null) {
// Create a copy of the graphics, with which you can play...
Graphics2D graphics = (Graphics2D) g.create();
try {
Rectangle back_rect = new Rectangle(0, 0, getWidth(),
getHeight());
graphics.setColor(Color.GREEN);
graphics.fill(back_rect);
// What's this trying to do...
// Where do you produce this???
// Because I didn't know where the image was been produced
// I commented out the code, but you should be aware
// That if the image is null, you triangles will never paint...
// if (image != null) {
// int width = Math.round(image.getWidth() * magnification);
// int height = Math.round(image.getHeight() * magnification);
//
// Rectangle image_rect = new Rectangle(offset.x, offset.y,
// width, height);
// graphics.setColor(Color.BLACK);
// graphics.draw(image_rect);
// graphics.drawImage(image, offset.x, offset.y, width,
// height, null);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (int pos = 0; pos < triangles.size(); pos++) {
Point[] current = triangles.get(pos);
ArrayList<Point> current_triangle = new ArrayList<Point>(3);
current_triangle.add(current[0]);
current_triangle.add(current[1]);
current_triangle.add(current[2]);
drawRegion(graphics, current_triangle);
}
//} // From the image != null
} finally {
graphics.dispose();
}
}
I'd also suggest you have a read through
2D Graphics
Performing Custom Painting in Swing
If you haven't already ;)
This article will give you all the info you need http://java.sun.com/products/jfc/tsc/articles/painting/
but I think you are missing -
super.paintComponent(g);
public class MyPanel extends JPanel {
protected void paintComponent(Graphics g) {
// Let UI delegate paint first
// (including background filling, if I'm opaque)
super.paintComponent(g);
// paint my contents next....
}
}
I worked out how to draw triangles on the image, when passing through an arrayList, where each Point[] represents the points of the triangle.
Note that this is now in a single entire class which is passed the information, rather than trying to call repaint from another class.
public AnnotatedDisplayTriangles(BufferedImage image, String image_path, ArrayList<Point[]> triangles) {
this.image = image;
this.image_path = image_path;
this.triangles = triangles;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw image centered.
int x = (getWidth() - image.getWidth())/2;
int y = (getHeight() - image.getHeight())/2;
g.drawImage(image, x, y, this);
Stroke drawingStroke = new BasicStroke(2);
Graphics2D graph = (Graphics2D)g;
graph.setStroke(drawingStroke);
graph.setPaint(Color.black);
for(int p = 0; p < triangles.size(); p++){
Point[] current_triangles = triangles.get(p);
for(int triangle = 0; triangle < current_triangles.length; triangle++ ){
Point current = current_triangles[triangle];
Point next;
if(triangle == current_triangles.length -1 )
next = current_triangles[0];
else
next = current_triangles[triangle + 1];
Line2D line = new Line2D.Double(current.x, current.y, next.x, next.y);
graph.draw(line);
}
}
}
public static void main(String image_path,ArrayList<Point[]> triangles, String panel_name) throws IOException {
String path = image_path;
BufferedImage image = ImageIO.read(new File(path));
AnnotatedDisplayTriangles contentPane = new AnnotatedDisplayTriangles(image, path, triangles);
// You'll want to be sure this component is opaque
// since it is required for contentPanes. Some
// LAFs may use non-opaque components.
contentPane.setOpaque(true);
int w = image.getWidth();
int h = image.getHeight();
JFrame f = new JFrame(panel_name);
// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(contentPane);
f.setSize(w,h);
f.setLocation(200,200);
f.setVisible(true);
}

Categories

Resources