Difference between revisions of "CISC181 F2017 JFrameExample"
From class_wiki
(→Custom JComponent class) |
(→Custom JComponent class) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 61: | Line 61: | ||
} | } | ||
− | // are any existing circles separated from the one at index i by *<= tolerance* pixels? | + | // are any existing circles separated from the proposed one at index i by *<= tolerance* pixels? |
boolean anyCirclesOverlap(int i, int tolerance) { | boolean anyCirclesOverlap(int i, int tolerance) { | ||
Line 104: | Line 104: | ||
else { | else { | ||
− | circleR[i]--; // retract to | + | circleR[i]--; // retract to the step before touch |
return true; | return true; | ||
} | } | ||
Line 134: | Line 134: | ||
for (int i = 0; i < numCircles; i++) { | for (int i = 0; i < numCircles; i++) { | ||
− | g.drawOval(circleX[i]-circleR[i], circleY[i]-circleR[i], 2*circleR[i], 2*circleR[i]); | + | g.drawOval(circleX[i] - circleR[i], circleY[i] - circleR[i], 2 * circleR[i], 2 * circleR[i]); |
} | } | ||
} | } | ||
} | } | ||
</nowiki> | </nowiki> |
Latest revision as of 07:14, 20 September 2017
Main class
package cisc181.mylab_2; // Christopher Rasmussen import javax.swing.JFrame; public class Lab2 { public static void main(String[] args) { JFrame myFrame = new JFrame(); myFrame.setSize(500, 500); myFrame.setTitle("Color Test"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ColorJComponent myComponent = new ColorJComponent(500, 500); myFrame.add(myComponent); myFrame.setVisible(true); // setVisible() *after* add() is the norm } }
Custom JComponent class
package cisc181.mylab_2; // Christopher Rasmussen import javax.swing.JComponent; import java.util.Random; import java.awt.Graphics; public class ColorJComponent extends JComponent { int[] circleX; int[] circleY; int[] circleR; final int MIN_RADIUS = 5; final int MAX_RADIUS = 15; final int MIN_SEPARATION = 1; final int MAX_ATTEMPTS = 5000; final int MAX_CIRCLES = 1000; Random rand; int initialWidth; int initialHeight; int numCircles; // actual number of circles drawn // are circles at index i and index j separated by *<= tolerance* pixels? boolean twoCirclesOverlap(int i, int j, int tolerance) { double distanceBetweenCenters = Math.sqrt((circleX[i] - circleX[j]) * (circleX[i] - circleX[j]) + (circleY[i] - circleY[j]) * (circleY[i] - circleY[j])); return (distanceBetweenCenters <= (circleR[i] + circleR[j] + tolerance)); } // are any existing circles separated from the proposed one at index i by *<= tolerance* pixels? boolean anyCirclesOverlap(int i, int tolerance) { for (int j = 0; j < i; j++) { if (twoCirclesOverlap(i, j, tolerance)) { return true; } } return false; } // attempt to randomly place the largest-possible circle that does not overlap any existing one boolean tryToPlaceCircle(int i) { for (int j = 0; j < MAX_ATTEMPTS; j++) { // pick a random position, set initial radius to minimum circleX[i] = rand.nextInt(initialWidth); circleY[i] = rand.nextInt(initialHeight); circleR[i] = MIN_RADIUS; // grow circle until it touches another or reaches max size while (!anyCirclesOverlap(i, MIN_SEPARATION) && circleR[i] < MAX_RADIUS) circleR[i]++; // it was touching from the start -- must try again if (circleR[i] == MIN_RADIUS) { continue; } // grew to max size -- well done else if (circleR[i] == MAX_RADIUS) { return true; } // grew some, but then touched else { circleR[i]--; // retract to the step before touch return true; } } // all attempts failed return false; } ColorJComponent(int width, int height) { circleX = new int[MAX_CIRCLES]; circleY = new int[MAX_CIRCLES]; circleR = new int[MAX_CIRCLES]; initialWidth = width; initialHeight = height; rand = new Random(); numCircles = 0; while (numCircles < MAX_CIRCLES && tryToPlaceCircle(numCircles)) { numCircles++; } } public void paintComponent(Graphics g) { for (int i = 0; i < numCircles; i++) { g.drawOval(circleX[i] - circleR[i], circleY[i] - circleR[i], 2 * circleR[i], 2 * circleR[i]); } } }