import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.concurrent.*;
import java.lang.reflect.*;
/**
* This class supports the output of graphical objects like points, lines,
* circles and rectangles in a window.
*
* @author Florian Latifi
*/
public final class Window {
private final JPanel panel;
private final Graphics2D graphics;
private Window(JPanel panel, Graphics2D graphics) {
this.panel = panel;
this.graphics = graphics;
}
/**
* Creates a window with a given width and height, and shows it on the screen.
*
* @param width the width of the window
* @param height the height of the window
*/
public static Window create(int width, int height) {
RunnableFuture<Window> initTask = new FutureTask<Window>(() -> {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
graphics.fillRect(0, 0, width, height);
JFrame frame = new JFrame();
JPanel panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.drawImage(image, 0, 0, width, height, null);
g2.dispose();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
};
frame.setContentPane(panel);
frame.setTitle("Window");
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
return new Window(panel, graphics);
});
SwingUtilities.invokeLater(initTask);
try {
return initTask.get();
} catch (InterruptedException e) {
return null;
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
/**
* Clears the content of the window.
*/
public void clear() {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.fillRect(0, 0, panel.getWidth(), panel.getHeight());
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Draws a point at a given position.
*
* @param x the x-coordinate for the point
* @param y the y-coordinate for the point
*/
public void drawPoint(int x, int y) {
drawPoint(x, y, Color.BLACK);
}
/**
* Draws a line between two given points.
*
* @param x1 the x-coordinate for the first point
* @param y1 the y-coordinate for the first point
* @param x2 the x-coordinate for the second point
* @param y2 the y-coordinate for the second point
*/
public void drawLine(int x1, int y1, int x2, int y2) {
drawLine(x1, y1, x2, y2, Color.BLACK);
}
/**
* Draws a rectangle at a top-left position, and with a specific width and
* height.
*
* @param x the top-left x-coordinate for the rectangle
* @param y the top-left y-coordinate for the rectangle
* @param w the width for the rectangle
* @param h the height for the rectangle
*/
public void drawRectangle(int x, int y, int w, int h) {
drawRectangle(x, y, w, h, Color.BLACK);
}
/**
* Draws a circle at a given center position, and with a specific radius.
*
* @param x the center x-coordinate for the circle
* @param y the center y-coordinate for the circle
* @param r the radius for the circle
*/
public void drawCircle(int x, int y, int r) {
drawCircle(x, y, r, Color.BLACK);
}
/**
* Draws a text at a given position.
*
* @param text the text to draw
* @param x the x-coordinate for the text
* @param y the y-coordinate for the text
*/
public void drawText(String text, int x, int y) {
drawText(text, x, y, Color.BLACK);
}
/**
* Draws a point at a given position, and with a specific color.
*
* @param x the x-coordinate for the point
* @param y the y-coordinate for the point
* @param color the color for the point
*/
public void drawPoint(int x, int y, Color color) {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.setColor(color);
graphics.fillRect(x - 1, y - 1, 3, 3);
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Draws a line from between two given coordinates, and with a specific color.
*
* @param x1 the x-coordinate for the first point
* @param y1 the y-coordinate for the first point
* @param x2 the x-coordinate for the second point
* @param y2 the y-coordinate for the second point
* @param color the color for the line
*/
public void drawLine(int x1, int y1, int x2, int y2, Color color) {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.setColor(color);
graphics.drawLine(x1, y1, x2, y2);
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Draws a rectangle at a given top-left position, and with a specific width,
* height, and color.
*
* @param x the top-left x-coordinate for the rectangle
* @param y the top-left y-coordinate for the rectangle
* @param w the width for the rectangle
* @param h the height for the rectangle
* @param color the color for the rectangle
*/
public void drawRectangle(int x, int y, int w, int h, Color color) {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.setColor(Color.BLACK);
graphics.drawRect(x, y, w, h);
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Draws a circle at a given center position, and with a specific radius and
* color.
*
* @param x the center x-coordinate for the circle
* @param y the center y-coordinate for the circle
* @param r the radius for the circle
* @param color the color for the circle
*/
public void drawCircle(int x, int y, int r, Color color) {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.setColor(color);
graphics.drawOval(x - r, y - r, 2 * r, 2 * r);
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Draws a text at a given position, and with a specific color.
*
* @param text the text to draw
* @param x the x-coordinate for the text
* @param y the y-coordinate for the text
* @param color the color for the text
*/
public void drawText(String text, int x, int y, Color color) {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.setColor(color);
graphics.drawString(text, x, y);
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Fills a rectangle at a given top-left position, and with a specific width,
* height, and color.
*
* @param x the top-left x-coordinate for the rectangle
* @param y the top-left y-coordinate for the rectangle
* @param w the width for the rectangle
* @param h the height for the rectangle
* @param color the color for the rectangle
*/
public void fillRectangle(int x, int y, int w, int h, Color color) {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.setColor(color);
graphics.fillRect(x, y, w, h);
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* Fills a circle at a given center position, and with a specific radius and
* color.
*
* @param x the center x-coordinate for the circle
* @param y the center y-coordinate for the circle
* @param r the radius for the circle
* @param color the color for the circle
*/
public void fillCircle(int x, int y, int r, Color color) {
try {
SwingUtilities.invokeAndWait(() -> {
graphics.setColor(color);
graphics.fillOval(x - r, y - r, 2 * r, 2 * r);
panel.repaint();
});
} catch (InterruptedException e) {
return;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
class Point {
final int x;
final int y;
Point(int x,int y) {
this.x = x;
this.y = y;
}
static Point fromInput() {
int x = In.readInt();
int y = In.readInt();
if (In.done()) return new Point(x,y);
else return null;
}
void draw(Window w){
w.drawPoint(x,y);
}
}
class Line {
final int x1;
final int y1;
final int x2;
final int y2;
Line(int x1,int y1,int x2,int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
Line fromInput() {
int x1 = In.readInt();
int y1 = In.readInt();
int x22 = In.readInt();
int y2 = In.readInt();
if (In.done()) return new Line(x1,y1,x2,y2);
else return null;
}
void draw(Window w){
w.drawLine(x1, y1, x2, y2);
}
}
class Rectangle {
final int x;
final int y;
final int w1;
final int h;
Rectangle(int x,int y,int w1,int h) {
this.x = x;
this.y = y;
this.w1 = w1;
this.h = h;
}
Rectangle fromInput() {
int x = In.readInt();
int y = In.readInt();
int w1 = In.readInt();
int h = In.readInt();
if (In.done()) return new Rectangle(x,y,w1,h);
else return null;
}
void draw(Window w){
w.drawRectangle(x,y,w1,h );
}
}
class Circle {
final int x;
final int y;
final int r;
Circle(int x,int y,int r) {
this.x = x;
this.y = y;
this.r = r;
}
Circle fromInput() {
int x = In.readInt();
int y = In.readInt();
int r = In.readInt();
if (In.done()) return new Circle(x,y,r);
else return null;
}
void draw(Window w){
w.drawCircle(x, y, r );
}
}
}