Difference between revisions of "CISC181 F2017 JFrameExample"

From class_wiki
Jump to: navigation, search
(Created page with "===Main class=== <nowiki> package cisc181.mylab_2; // Christopher Rasmussen import javax.swing.JFrame; public class Lab2 { public static void main(String[] args...")
 
(Custom JComponent class)
 
(3 intermediate revisions by the same user not shown)
Line 34: Line 34:
  
 
  import javax.swing.JComponent;
 
  import javax.swing.JComponent;
  import java.awt.Color;
+
  import java.util.Random;
 
  import java.awt.Graphics;
 
  import java.awt.Graphics;
  
  public class MyJComponent extends JComponent {
+
  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
  
    public void paintComponent(Graphics g) {
+
  // are circles at index i and index j separated by *<= tolerance* pixels?
  
        final int SIDE_LENGTH = 16;
+
  boolean twoCirclesOverlap(int i, int j, int tolerance) {
         int gridInterval = 20;
+
    double distanceBetweenCenters =
        int xOffset = (gridInterval - SIDE_LENGTH) / 2;   // so that grid is centered
+
         Math.sqrt((circleX[i] - circleX[j]) * (circleX[i] - circleX[j]) +
        int yOffset = xOffset;
+
                  (circleY[i] - circleY[j]) * (circleY[i] - circleY[j]));
 +
    return (distanceBetweenCenters <= (circleR[i] + circleR[j] + tolerance));
 +
  }
  
        // grid of alternating colors and shapes
+
  // are any existing circles separated from the proposed one at index i by *<= tolerance* pixels?
  
        for (int y = 0; y < getHeight(); y += gridInterval) {
+
  boolean anyCirclesOverlap(int i, int tolerance) {
            for (int x = 0; x < getWidth(); x += gridInterval) {
+
    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++) {
  
                // red squares on even rows and columns
+
      // pick a random position, set initial radius to minimum
  
                if ((y % (2 * gridInterval)) == 0 || (x % (2 * gridInterval)) == 0) {
+
      circleX[i] = rand.nextInt(initialWidth);
                    g.setColor(Color.RED);
+
      circleY[i] = rand.nextInt(initialHeight);
                    g.fillRect(xOffset + x, yOffset + y, SIDE_LENGTH, SIDE_LENGTH);
+
      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++;
 +
    }
 +
  }
  
                // blue circles otherwise
+
  public void paintComponent(Graphics g) {
  
                else {
+
    for (int i = 0; i < numCircles; i++) {
                    g.setColor(Color.BLUE);
+
      g.drawOval(circleX[i] - circleR[i], circleY[i] - circleR[i], 2 * circleR[i], 2 * circleR[i]);
                    g.fillOval(xOffset + x, yOffset + y, SIDE_LENGTH, SIDE_LENGTH);
 
                }
 
            }
 
        }
 
 
     }
 
     }
 +
  }
 
  }
 
  }
 
</nowiki>
 
</nowiki>

Latest revision as of 08: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]);
     }
   }
 }