How can I recreate my graphic using recursion? - java

I have a graphic which consists of a horizontal line of circles of different sizes at regular intervals. Here is the picture:
I am trying to recreate this graphic using recursion as opposed to the if statements used in my code but after trying, am unsure about how to do this. Would love some help, here is my code:
package weekFour;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
#SuppressWarnings("serial")
public class Circle extends JPanel {
private int circX = 10;
private static int windowW = 1700;
private static int windowH = 1000;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //smoothes out edges
Color c5 = new Color(50, 50, 50);
Color c4 = new Color(100, 100, 100);
Color c3 = new Color(150, 150, 150);
Color c2 = new Color(200, 200, 200);
Color c1= new Color(250, 250, 250);
for (int i = 0; i < 1; i++) {
g2.setColor(c1);
g2.fillOval(522 + 75*i, 138, 666, 666);
g2.setColor(c1);
g2.drawOval(522 + 75*i, 138, 666, 666);
}
for (int i = 0; i < 3; i++) {
g2.setColor(c2);
g2.fillOval(244 + 522*i, 365, 180, 180);
g2.setColor(c2);
g2.drawOval(244 + 522*i, 365, 180, 180);
}
for (int i = 0; i < 10; i++) {
g2.setColor(c3);
g2.fillOval(130 + 174*i, 428, 60, 60);
g2.setColor(c3);
g2.drawOval(130 + 174*i, 428, 60, 60);
}
for (int i = 0; i < 25; i++) {
g2.setColor(c4);
g2.fillOval(60 + 87*i, 444, 25, 25);
g2.setColor(c4);
g2.drawOval(60 + 87*i, 444, 25, 25);
}
for (int i = 0; i < 120; i++) {
g2.setColor(c5);
g2.fillOval(circX + 29*i, 450, 12, 12);
g2.setColor(c5);
g2.drawOval(circX + 29*i, 450, 12, 12);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("MyTaskToo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Circle());
frame.setSize(windowW, windowH);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Thanks for your time.

This is how I went about this problem, although we had to do it with green circles as opposed to grey circles but it's not that different.
N.B: Sorry for the appealing comments for sometimes trivial things but we get marks for commenting and it is better to be safe than sorry. Maybe they change you some insight into the thought process.
Here is the main method that starts the programme and sets out the window information.
public class Q2Main {
public static void main(String[] args) {
// here we are just setting out the window end putting the circles drawin in Q2Circles into this window.
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(1000, 500);
window.getContentPane().add(new Q2Circles(5));
window.setVisible(true);
}}
This is where the magic happens:
public class Q2Circles extends JPanel {
// this allows the user to specify how many loops of recursion they want the programme to complete before finishing
int recursionsToDo;
public Q2Circles(int recursionMax){
super();
recursionsToDo = recursionMax;
}
/*
this method is automatically called when we run the constructor as it inherits from the JFram superclass. here
we are setting out the size of the circle by getting the size of the window to make it proportional to the rest
of the screen and circles.
we then pass these values into the drawCircle method to draw the circle
*/
public void paintComponent(Graphics g){
Rectangle rectangle = this.getBounds();
int diameter = rectangle.width/3;
int centerPoint = rectangle.width/2;
drawCircle(g, 1, centerPoint, diameter);
}
/*
This method is where the magic of the programme really takes place. first of all we make sure we haven't completed
the necessary recursions. we the set the color by dividing it by the amount of times we have recursed, this will
have the affect of getting darker the more times the method recurses. we then sset the color. finaly we fill the
oval (draw the circle). because we want to move depending on the times it has recursed and size of the previous
we do it based on the size of the elements from the previous call to this method. Getting the right numbers
though was just alot of trial and error.
we then increment the recursion counter so that we know how many times we have recursed and that can then be
used at different points where needed. e.g for setting the color.
each recursive call used the dimension of the other recursive calls to make the whole picture. Although the
first recursive call creates the circles on the right of the screen. the second call draws the circle on the
left of the screen and the last one does the circles in the middle, they all use eachothers values to make it
complete. without one recursive step, more is missing than just what is created by that recursive call on its own.
in all honesty though, there is alot of duplication, like the large middlecircle.
*/
public void drawCircle(Graphics g, int amountOfRecursions, int center, int diameter){
if (amountOfRecursions <= recursionsToDo){
int recursionsCount = amountOfRecursions;
int greenColor = Math.round(225 / (amountOfRecursions));
g.setColor(new Color(0, greenColor, 0));
g.fillOval(center - (diameter/2), 200 - (diameter/2), diameter, diameter);
recursionsCount++;
drawCircle(g, recursionsCount, Math.round(center + diameter), diameter/3);
drawCircle(g, recursionsCount, Math.round(center - diameter), diameter/3);
drawCircle(g, recursionsCount, Math.round(center), diameter/3);
}
}}

Related

Not sure if I am overriding paintComponent() correctly [duplicate]

This question already has an answer here:
Circle not showing up in JPanel
(1 answer)
Closed 2 years ago.
For someone who is wanting to learn more about awt/swing and who has not worked a lot with awt/swing I'm not sure if I am doing this correctly or not. What I am trying to do is override paintComponent() with a method that creates 6 circles that are supposed to be added to the inner panel in certain spots (the x + 50 and y + 50 are just for testing purposes). I've looked through online resources including this site and the circles still don't appear to be showing up. I'm sure I am doing something wrong but I am not sure what. Tips and/or informative links would be greatly appreciated
This is the class I have with the goal of creating and adding the circles to the panel:
public class TimeUnit extends JPanel {
private static final long serialVersionUID = 1L;
private int x = -50;
private int y = -50;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
ArrayList<Graphics> list = new ArrayList<Graphics>(6);
for (int i = 0; i < 6; i++) {
list.add(g.create());
}
for (Graphics r : list) {
r.drawOval(x + 50, y + 50, 50, 50);
}
}
And this is where it is incorporated into my main program:
JPanel inner = new JPanel();
inner.setLayout(null);
inner.setSize(325, 570);
inner.setBackground(null);
inner.setLocation(500, 350);
inner.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.BLACK));
inner.setVisible(true);
inner.repaint();
//----Containers to Panel/Panel to Frame---------
Panel.add(inner);
Panel.add(labelOne);
Panel.add(labelTwo);
Panel.add(labelFour);
Panel.add(labelEight);
Panel.add(timeLabel);
frame.add(Panel, BorderLayout.CENTER);
You should use the passed in Graphics g to draw the ovals, not create new Graphics objects:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < 6; i++) {
g.drawOval(x + 50*i, y + 50*i, 50, 50);
}
}

Fill an oval every second

I've got 8 ovals all set to the same colour. After a second I want the first oval to change colours and then after another second i want the first oval to go back to its original colour and then change the second ovals colour. I've drawn the circles and I've tried implementing a thread but i think it's not executing...
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Circle extends JPanel implements Runnable
{
Graphics g;
Thread t = new Thread();
int[][] fillCircles = new int[8][4];
#Override
public void paintComponent(Graphics g)
{
this.g = g;
super.paintComponent(this.g);
this.g.setColor(new java.awt.Color(237, 54, 26));
this.g.drawOval(300, 50, 100, 100);
this.g.drawOval(450, 125, 100, 100);
this.g.drawOval(500, 250, 100, 100);
this.g.drawOval(425, 375, 100, 100);
this.g.drawOval(300, 400, 100, 100);
this.g.drawOval(175, 350, 100, 100);
this.g.drawOval(125, 225, 100, 100);
this.g.drawOval(175, 100, 100, 100);
this.g.fillOval(300, 50, 100, 100);
this.g.fillOval(450, 125, 100, 100);
this.g.fillOval(500, 250, 100, 100);
this.g.fillOval(425, 375, 100, 100);
this.g.fillOval(300, 400, 100, 100);
this.g.fillOval(175, 350, 100, 100);
this.g.fillOval(125, 225, 100, 100);
this.g.fillOval(175, 100, 100, 100);
fillCircles[0][0] = 300;
fillCircles[0][1] = 50;
fillCircles[0][2] = 100;
fillCircles[0][3] = 100;
fillCircles[1][0] = 450;
fillCircles[1][1] = 125;
fillCircles[1][2] = 100;
fillCircles[1][3] = 100;
fillCircles[2][0] = 500;
fillCircles[2][1] = 250;
fillCircles[2][2] = 100;
fillCircles[2][3] = 100;
fillCircles[3][0] = 425;
fillCircles[3][1] = 375;
fillCircles[3][2] = 100;
fillCircles[3][3] = 100;
fillCircles[4][0] = 300;
fillCircles[4][1] = 400;
fillCircles[4][2] = 100;
fillCircles[4][3] = 100;
fillCircles[5][0] = 175;
fillCircles[5][1] = 350;
fillCircles[5][2] = 100;
fillCircles[5][3] = 100;
fillCircles[6][0] = 125;
fillCircles[6][1] = 225;
fillCircles[6][2] = 100;
fillCircles[6][3] = 100;
fillCircles[7][0] = 175;
fillCircles[7][1] = 100;
fillCircles[7][2] = 100;
fillCircles[7][3] = 100;
}
Circle () {
t.start();
}
public void run () {
int circle = 0;
try {
for (;;) {
Thread.sleep(1000);
if (circle > 0) {
this.g.setColor(new java.awt.Color(237, 54, 26));
circle--;
this.g.fillOval(fillCircles[circle][0], fillCircles[circle][1], fillCircles[circle][2], fillCircles[circle][2]);
circle++;
}
this.g.setColor(Color.red);
this.g.fillOval(fillCircles[circle][0], fillCircles[circle][1], fillCircles[circle][2], fillCircles[circle][2]);
circle++;
if (circle == 8) {
circle = 0;
}
}
} catch (InterruptedException e) {
System.out.println ("Thread Interrupted");
}
}
public static void main(String[] args) {
Circle c;
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(c=new Circle());
application.setSize(1200, 900);
application.setVisible(true);
}
}
You're just instantiating a Thread without giving it a Runnable, so it's not running what you're intending.
Thread t = new Thread();
should be
Thread t = new Thread(this);
this because the Circle is Runnable and the run() method is in it.
Regarding color changing, I would give you an idea.
When drawing the circles, check the current circle number/index against another variable which changes every second colorChangeIndex
if(circleIndex == colorChangeIndex){
// another color
else
//the default color
colorChangeIndex++; (modulo number of cricles to reset it)
The basic structure of your code is wrong. Painting should only be done in the paintComponent() method. You should never reference the Graphics object in your thread.
So, instead what you might want to do is keep an ArrayList of "circle" objects. This custom object will contain the circle to be painted and its color. Then in the paintComponent() method you just iterate through the ArrayList and paint all the circles in the ArrayList. Check out the DrawOnComponent example found in Custom Painting Approches.
After a second I want the first oval to change colours and then after another second i want the first oval to go back to its original colour and then change the second ovals colour.
So now you need to use a Swing Timer to animate the painting. When the Timer fires you reset the Color of the appropriate circle and then just repaint the panel.

Java Checkers Game Moving Pieces

I am trying to build a java program that allows a user to play checkers. Right now I'm having trouble creating my 24 pieces & getting them to move from place to place. I want to be able to drag them from an orange square to another orange square. If the square isn't orange, I want it the program to reject the move. How can I go about doing this? Any & all help is appreciated!
import java.awt.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class Board extends JPanel{
public void paint(Graphics g){
g.setColor(new Color(234, 106,32));
g.fillRect(0, 0, 400, 400);
for(int i = 0; i <= 350; i+=100){
for(int j = 0; j <= 350; j+=100){
g.clearRect(i, j, 50, 50);
}
}
for(int i = 50; i <= 400; i+=100){
for(int j = 50; j <= 400; j+=100){
g.clearRect(i, j, 50, 50);
}
}
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(400,420);
frame.getContentPane().add(new Board());
frame.setTitle("Java Chip Checkers");
frame.setLocationRelativeTo(null);
/* frame.setBackground(new Color(234, 106, 32)); */
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
If it is not a training project to study JPanel, i recommend using a framework specifically designed for games. (libgdx eg) Otherwise, you have to write a lot of unnecessary interactions.
You need a binary matrix and translation of the mouse coordinates in the matrix. Then you will be easy to calculate the actions of the user.
But your question is not very suitable for stackoverflow.

Graph plotting in Java Swing only draws points

I'm currently working on a program where certain numerical variables, which evolve over time, have their value displayed on each iteration. That works well enough, but now I want to plot a graph that shows their evolution over time.
So, I looked into an example of code for plotting graphs in Swing. My final code looks like this:
public class Populus3 extends JPanel
{
public static void main(String[] args) throws IOException {
final Populus3 pop = new Populus3();
JFrame f = new JFrame(); //where I want to plot the graph
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new GraphingData());
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
frame = new JFrame("Animation Frame"); //where I'm running animation for another element of the program
frame.add(pop, BorderLayout.CENTER);
frame.setSize(graphSize, graphSize);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//insert all sort of things
}
public void paint(Graphics g)
{
super.paint(g);
paintCell(g, 1);
Toolkit.getDefaultToolkit().sync(); // necessary for linux users to draw and animate image correctly
g.dispose();
}
public void actionPerformed(ActionEvent e) {
repaint();
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int i = 0; i < particleType.length; i++)
paintCell(g, i); //a method that draws a small circle for the animation panel
}
public static class GraphingData extends JPanel {
int[] data = {
21, 14, 18, 03, 86, 88, 74, 87, 54, 77,
61, 55, 48, 60, 49, 36, 38, 27, 20, 18
};
final int PAD = 20;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
// Draw ordinate.
g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
// Draw abcissa.
g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
double xInc = (double)(w - 2*PAD)/(data.length-1);
double scale = (double)(h - 2*PAD)/getMax();
// Mark data points.
g2.setPaint(Color.red);
for(int i = 0; i < data.length; i++) {
double x = PAD + i*xInc;
double y = h - PAD - scale*data[i];
g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));
}
}
private int getMax() {
int max = -Integer.MAX_VALUE;
for(int i = 0; i < data.length; i++) {
if(data[i] > max)
max = data[i];
}
return max;
}
}
}
Now, the animation panel works just fine. The graph panel, on the other hand...when I run the program, it displays a bunch of red dots, without lines to connect them. What am I doing wrong?
In addition to #Hovercraft's helpful suggestions, also consider these other approaches:
Accumulate the points in a GeneralPath that may be rendered as required, for example.
Connect the points using repeated calls to drawLine() using a suitable coordinate system, outlined here.
Look at JFreeChart.
Your code confuses me:
You override both paint and paintComponent for your Populus3 JPanel -- why? You should only override paintComponent unless you absolutely have to have your drawing affect a component's children and borders.
You dispose of the Graphics object passed into paint -- a very dangerous thing to do. You should never dispose of a Graphics object given to you by the JVM, only Graphics objects that you yourself create.
You repeatedly call a method not defined here for us, paintCell(...).
I've never heard of the need for Toolkit.getDefaultToolkit().sync(); for Swing applications. Do you have a reference for this need?
You mention "animation" but I see no animation code.
In your GraphingData class's paintComponent method you fill ellipses in your for loop, but you don't connect them with lines ever, so it shouldn't be surprising that you're only seeing dots in your graph and no lines.
Consider isolating your problem more and posting an sscce, a minimal test program that we can compile, run, modify and correct and that shows us your problem, but has no extra code not related to the problem or required for demonstration.
The following code demonstrates a real-time Java chart using XChart where the line is updated as the data evolves over time. Creating real-time charts is as simple as calling updateXYSeries for one or more series objects through the XYChart instance and triggering a redraw of the JPanel containing the chart. This works for all chart types including XYChart, CategoryChart, BubbleChart and PieChart, for which example source code can be found here: https://github.com/timmolter/XChart/tree/develop/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/realtime. Examples demonstrate using the SwingWrapper with repaintChart() method as well as XChartPanel with revalidate() and repaint(). Disclaimer, I'm the main developer of the XChart library.
public class SimpleRealTime {
public static void main(String[] args) throws Exception {
double phase = 0;
double[][] initdata = getSineData(phase);
// Create Chart
final XYChart chart = QuickChart.getChart("Simple XChart Real-time Demo", "Radians", "Sine", "sine", initdata[0], initdata[1]);
// Show it
final SwingWrapper<XYChart> sw = new SwingWrapper<XYChart>(chart);
sw.displayChart();
while (true) {
phase += 2 * Math.PI * 2 / 20.0;
Thread.sleep(100);
final double[][] data = getSineData(phase);
chart.updateXYSeries("sine", data[0], data[1], null);
sw.repaintChart();
}
}
private static double[][] getSineData(double phase) {
double[] xData = new double[100];
double[] yData = new double[100];
for (int i = 0; i < xData.length; i++) {
double radians = phase + (2 * Math.PI / xData.length * i);
xData[i] = radians;
yData[i] = Math.sin(radians);
}
return new double[][] { xData, yData };
}
}
This results in the following Java Swing real-time chart app:

Dynamic Graphics Object Painting

Trying to figure out the best way to do this (And without crossing any specifics DO NOTs that I don't know about).
I'm working on visually displaying a graph (Various nodes, with edges connecting them) with circles and lines to represent such. Each node will be added during runtime and I can't hardcode this. From what I understand, all painting needs to be done in the paint(Graphics g) method - which isn't that helpful, since I can't be change the parameters and it seems this is only called during the initial creation?
Right now I was thinking about having it call various other methods, passing the Graphics object, and depending on other variables - I'll decide whether that's what I even want to call (Since the paint() method is the only one I can call).
Am I going about this completely wrong? Never bothered with this before.
To give you a better idea of what I want to end up with: I want to be able to pass the coordinates of the shape I want to add for the node, and then add it to whatever I have on the graph so far. And then same with the edges, I want to be able to pass the beginning and end point of the line to repaint on top of whatever is existing at that time.
Not exactly what I want right now - but you'll get the idea from what I patched together so far:
import java.awt.*;
import javax.swing.*;
public class MyCanvas extends Canvas
{
public MyCanvas()
{
}
public void paint(Graphics graphics)
{
// Keep this until I figured out if it's painted on load or not.
graphics.drawLine(10, 20, 350, 380);
}
public static void main(String[] args)
{
MyCanvas canvas = new MyCanvas();
JFrame frame = new JFrame();
int vertexes = 0;
// Change this next part later to be dynamic.
vertexes = 10;
int canvasSize = vertexes * vertexes;
frame.setSize(canvasSize, canvasSize);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(canvas);
frame.setVisible(true);
}
public void drawNode(int x, int y, Graphics g)
{
// Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5
int xLoc = (x*10) - 5;
int yLoc = (y*10) - 5;
g.setColor(Color.white);
g.fillOval(xLoc, yLoc, 8, 8);
g.drawOval(xLoc, yLoc, 8, 8);
}
public void drawArc(int x, int y, int xx, int yy, Graphics g)
{
int xLoc = (x*10) - 5;
int yLoc = (y*10) - 5;
int xxLoc = (xx*10) - 5;
int yyLoc = (yy*10) - 5;
g.drawLine(xLoc, yLoc, xxLoc, yyLoc);
}
}
Edit: (Response for Andrew)
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyCanvas extends JPanel
{
public MyCanvas() {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
public static void main(String[] args)
{
int vertexes = 0;
// Change this next part later to be dynamic.
vertexes = 10;
int canvasSize = vertexes * vertexes;
JFrame frame = new JFrame();
JLabel label = new JLabel();
BufferedImage bImage = new BufferedImage(canvasSize, canvasSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bImage.createGraphics();
g2d.drawLine(50, 50, 300, 300);
ImageIcon iIcon = new ImageIcon(bImage);
label.setIcon(iIcon);
frame.add(label);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g2d = drawNode(1,1,g2d);
label.repaint();
}
public static Graphics2D drawNode(int x, int y,Graphics2D g2d)
{
// Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5
int xLoc = (x*10) - 5;
int yLoc = (y*10) - 5;
g2d.setColor(Color.white);
g2d.fillOval(xLoc, yLoc, 8, 8);
g2d.drawOval(xLoc, yLoc, 8, 8);
return g2d;
}
public static void drawArc(int x, int y, int xx, int yy)
{
int xLoc = (x*10) - 5;
int yLoc = (y*10) - 5;
int xxLoc = (xx*10) - 5;
int yyLoc = (yy*10) - 5;
// g.drawLine(xLoc, yLoc, xxLoc, yyLoc);
}
}
There are various strategies you might pursue for this.
If the objects are never removed from the drawing once done, use a BufferedImage, put it in a (ImageIcon in a) JLabel. When it comes time to update:
Get the graphics instance of the image and draw the new element.
Dispose of the graphics object.
Call repaint() on the label.
Keep a list of the drawn elements. In the paint method, paint them all. When a new element is added, call repaint() on the rendering component.
Here is an example of the 1st technique:
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
public class MyCanvas
{
JLabel view;
BufferedImage surface;
Random random = new Random();
public MyCanvas()
{
surface = new BufferedImage(600,400,BufferedImage.TYPE_INT_RGB);
view = new JLabel(new ImageIcon(surface));
Graphics g = surface.getGraphics();
g.setColor(Color.ORANGE);
g.fillRect(0,0,600,400);
g.setColor(Color.BLACK);
// Keep this until I figured out if it's painted on load or not.
g.drawLine(10, 20, 350, 380);
g.dispose();
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
addNewElement();
}
};
Timer timer = new Timer(200, listener);
timer.start();
}
public void addNewElement() {
boolean drawArc = random.nextBoolean();
int x = random.nextInt(60);
int y = random.nextInt(40);
Graphics g = surface.getGraphics();
if (drawArc) {
g.setColor(Color.BLUE);
int xx = random.nextInt(60);
int yy = random.nextInt(40);
drawArc(x,y,xx,yy,g);
} else {
drawNode(x,y,g);
}
g.dispose();
view.repaint();
}
public static void main(String[] args)
{
MyCanvas canvas = new MyCanvas();
JFrame frame = new JFrame();
int vertexes = 0;
// Change this next part later to be dynamic.
vertexes = 10;
int canvasSize = vertexes * vertexes;
frame.setSize(canvasSize, canvasSize);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(canvas.view);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public void drawNode(int x, int y, Graphics g)
{
// Treat each location as a 10x10 block. If position 1,1 then go to (5,5) - If position 3,5 then go to (25, 45) eg: (x*10)-5, (y*10)-5
int xLoc = (x*10) - 5;
int yLoc = (y*10) - 5;
g.setColor(Color.white);
g.fillOval(xLoc, yLoc, 8, 8);
g.drawOval(xLoc, yLoc, 8, 8);
}
public void drawArc(int x, int y, int xx, int yy, Graphics g)
{
int xLoc = (x*10) - 5;
int yLoc = (y*10) - 5;
int xxLoc = (xx*10) - 5;
int yyLoc = (yy*10) - 5;
g.drawLine(xLoc, yLoc, xxLoc, yyLoc);
}
}
Further tip
You might notice that the lines look quite 'jagged' & ugly. Both the BufferedImage or a JComponent has access to the more useful Graphics2D object (for the JComponent it is necessary to cast it in paintComponent()). A Graphics2D instance accepts rendering hints that can be used to smooth (dither) the elements drawn.

Categories