1

Can I take one of the MyHouse objects that I instantiate, and somehow set it to scale proportionately with its underlying NscComponent container?

When I use the setSize method, which is inherited from NscComponent, it does not change the size of the house1 MyHouse object. It makes the container smaller, but not the object, and the container resizes and clips out most of the house1 object. I had tried to create a new method inside MyHouse.java that resizes each of the MyHouse components that make up the whole house, and that worked, but then the coordinates were all screwed up and the house itself looked like it was all broken apart.

It seems like having to manipulate each individual component of MyHouse objects to resize defeats the whole point of creating an object.

Here is the MyHouse code:

/**
 * A new graphic component. This component is used in
 * the notes to highlight the process of designing a 
 * new object and then implementing it.
 *
 * @author Dan Jinguji
 * @author Chris Wilson
 * @version Demo: MyHouse
 */
public class MyHouse extends NscComponent {

  // instance variables
  private NscUpTriangle theRoof;
  private NscRectangle theWalls;
  private NscRectangle theDoor;
  private NscRectangle theWindow;
  private NscRectangle theWindowPane;


  /**
   * Constructor for objects of class MyHouse.
   * This creates a MyHouse object at the specified
   * location
   * @param x the x-coordinate for the object
   * @param y the y-coordinate for the object
   */
  public MyHouse(int x, int y)  {

    // Specify the constructor for the superclass
    super(x, y, 120, 90);

    // Create the roof object
    theRoof = new NscUpTriangle(0, 0, 120, 40);
    // Set the characteristics of the roof
    theRoof.setFilled(true);
    theRoof.setBackground(new java.awt.Color(0x99, 0x33, 0x00));
    // Place the roof in the MyHouse object
    add(theRoof);

    // Create the walls object
    theWalls = new NscRectangle(10, 40, 100, 50);
    // Set the characteristics of the walls
    theWalls.setFilled(true);
    theWalls.setBackground(java.awt.Color.blue);
    // Place the walls in the MyHouse object
    add(theWalls);

    // Create the door object
    theDoor = new NscRectangle(48, 50, 24, 40);
    // Set the characteristics of the door
    theDoor.setFilled(true);
    theDoor.setBackground(new java.awt.Color(0x99, 0x66, 0x33));
    // Place the door in the MyHouse object
    add(theDoor);

    // Create the window object
    theWindow = new NscRectangle(80, 50, 25, 20);
    // Set color
    theWindow.setFilled(true);
    theWindow.setBackground(java.awt.Color.white);
    // Create custom glass color
    java.awt.Color glass = new java.awt.Color(153, 255, 255);
    // Create window pane object
    theWindowPane = new NscRectangle(83, 53, 19, 14);
    // Set color
    theWindowPane.setFilled(true);
    theWindowPane.setBackground(glass);    
    // add window and pane
    add(theWindow);
    add(theWindowPane);
  }

  /*
   * Overloaded constructor for the MyHouse class
   * Creates the house objects and also inputs color variable
   * 
   * @param x the x-coordinate for the object
   * @param y the y-coordinate for the object
   * @param colorVar the color for the walls of the house
  */

  public MyHouse(int x, int y, java.awt.Color colorVar) {

    // constructor, call super before anything else
    super(x, y, 120, 90);    
    // build roof and set color, then add
    theRoof = new NscUpTriangle(0, 0, 120, 40);    
    theRoof.setFilled(true);
    theRoof.setBackground(new java.awt.Color(0x99, 0x33, 0x00));    
    add(theRoof);    
    // Create the walls and pass the 3rd constructor parameter for color conversion, then add    
    theWalls = new NscRectangle(10, 40, 100, 50);    
    theWalls.setFilled(true);
    theWalls.setBackground(colorVar);
    add(theWalls);

    // Create door, set color and add
    theDoor = new NscRectangle(48, 50, 24, 40);    
    theDoor.setFilled(true);
    theDoor.setBackground(new java.awt.Color(0x99, 0x66, 0x33));    
    add(theDoor);

    // Create the window object
    theWindow = new NscRectangle(80, 50, 25, 20);
    // Set color
    theWindow.setFilled(true);
    theWindow.setBackground(java.awt.Color.white);
    // Create custom glass color
    java.awt.Color glass = new java.awt.Color(153, 255, 255);
    // Create window pane object
    theWindowPane = new NscRectangle(83, 53, 19, 14);    
    theWindowPane.setFilled(true);
    theWindowPane.setBackground(glass);    
    // add window and pane
    add(theWindow);
    add(theWindowPane);

  }   

  /**
   * Change the color of the house
   * 
   * @param c The color for the walls of the house
   */
  public void setColor(java.awt.Color c) {
    theWalls.setBackground(c);
    repaint();
  }

  /**
   * Retrieve the color of the house
   * 
   * @return The color of the walls of the house
   */
  public java.awt.Color getColor() {
    return theWalls.getBackground();
  } 

}

Here is the MyScene code, which instantiates 3 MyHouse objects and places them into the scene.

// Allow short name access to java.awt.Color
import java.awt.Color;

/*
 * This is the shell for assignment: MyScene.
 * This program draws a simple scene using additional
 * classes that the student creates.
 * 
 * @author Dan Jinguji
 * @author Chris Wilson
 * @version Assignment 4: MyScene
 */
public class MyScene extends NscWindow {

   // instance variables
   private MyHouse house1;
   private MyHouse house2;
   private MyHouse house3;
   private MyTree tree1;
   private MyTree tree2;
   private MyTree tree3;

  /**
   * Constructor for objects of class MyScene
   */
  public MyScene() {
    // Specify the constructor for the superclass
    super(10, 10, 400, 300);
    // set characteristics for the object
    setTitle("My Scene");

    // Draw the sky
    getContentPane().setBackground(new Color(0x00, 0xCC, 0xFF));

    // Draw some grass
    NscRectangle grass = new NscRectangle(0, 100, 400, 200);
    grass.setBackground(new Color(0x00, 0x99, 0x00));
    grass.setFilled(true);
    add(grass);

    // instantiate new house objects
    house1 = new MyHouse(100, 50, Color.white);
    add(house1);    
    house2 = new MyHouse(200, 150);
    add(house2);    
    house3 = new MyHouse(0, 200, Color.orange);
    add(house3);    
    // request a rerendering of the window
    repaint();

    // instantiate new tree objects
    tree1 = new MyTree(35, 20, Color.white);
    add(tree1);
    tree2 = new MyTree(290, 50);
    add(tree2);
    tree3 = new MyTree(5, 60, Color.cyan);
    add(tree3);
    // request a rerender
    repaint();

  } 

  /**
   * Alter the scene, by changing color
   */
  public void change1() {
    // change the color of the houses and trees
    house1.setColor(Color.red);
    tree1.setColor(Color.black);    
    house2.setColor(Color.magenta);
    tree2.setColor(Color.orange);    
    house3.setColor(Color.black);
    tree3.setColor(Color.pink);
    // request a rerendering of the window
    repaint();
  }

   /**
    * Alter the scene, by changing location
    */
  public void change2() {
    // change the location of the houses and trees
    house1.setLocation(50, 125);    
    house2.setLocation(150, 25);    
    house3.setLocation(0, 150);
    tree1.setLocation(25, 10);
    tree2.setLocation(300, 20);
    tree3.setLocation(150, 90);
    // request a rerendering of the window
    repaint();
  }

   /**
    * Alter the scene, by changing size of objects and underlying containers   
    * 
    */
  public void change3() {
    house1.setSize(80, 60);
  } 



   /**
    * Alter the scene, restoring original settings
    */
  public void reset() {
    // reset the initial values for the house
    house1.setLocation(100, 50);
    house1.setColor(Color.white);
    house1.setSize(120, 90);    
    // reset the initial values for the house
    house2.setLocation(200, 150);
    house2.setColor(Color.blue);
    house2.setSize(120, 90);    
    // reset the initial values for the house
    house3.setLocation(0, 200);
    house3.setColor(Color.orange);
    house3.setSize(120, 90);
    // rest the initial values for the tree
    tree1.setLocation(35, 20);
    tree1.setColor(Color.white);
    tree1.setSize(60, 120);
    // rest the initial values for the tree
    tree2.setLocation(290, 50);
    tree2.setColor(Color.green);
    tree2.setSize(60, 120);
    // rest the initial values for the tree
    tree3.setLocation(5, 90);
    tree3.setColor(Color.cyan);
    tree3.setSize(60, 120);
    // request a rerendering of the window
    repaint();
  }

   /**
    * The application method, to test your code
    *
    * @param args The command-line arguments
    */
  public static void main(String[] args) {

    // declare a MyScene reference
    MyScene aScene;
    // instantiate MyScene
    aScene = new MyScene();
    // pause
    javax.swing.JOptionPane.showMessageDialog(null, "Press OK to continue");

    // test setColor
    aScene.change1();
    javax.swing.JOptionPane.showMessageDialog(null, "Press OK to continue");

    // test setLocation
    aScene.change2();
    javax.swing.JOptionPane.showMessageDialog(null, "Press OK to continue");

    // test setSize
    aScene.change3();
    javax.swing.JOptionPane.showMessageDialog(null, "Press OK to continue");    


    // reset initial values
    aScene.reset();
  }

}
durron597
  • 31,968
  • 17
  • 99
  • 158
Chris Wilson
  • 135
  • 3
  • 16
  • 5
    What the heck is an `NscComponent` or `NscWindow`? For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). Note if this is for a school project, if they wanted you to spend time figuring how to scale objects, they'd have mentioned that. Spare time would be better spent ensuring the code has no bugs, is easy to read, well documented, uses best practices, and that you can explain every line of code and why the lines are in the order they are (etc.)... – Andrew Thompson Jul 18 '15 at 16:00
  • 1
    *"Can I set the entire object to scale/fit inside its underlying container?"* Well if `NscComponent` extends `JComponent` it will have a `paintComponent(Graphics)` method that should actually be given a `Graphics2D` object. Once it has been cast back to `Graphics2D` it is possible to use (drum roll please..) [`Graphics2D.scale(sx,sy)`](https://docs.oracle.com/javase/8/docs/api/java/awt/Graphics2D.html#scale-double-double-) .. – Andrew Thompson Jul 18 '15 at 16:10
  • For [example](http://stackoverflow.com/a/5594424/230513). – trashgod Jul 18 '15 at 20:02

1 Answers1

0

Your problem is that you are specifying the sizes of every component manually. Of course it would be a gigantic pain to recalculate the sizes and locations of things if you specify them by hand! You would have to, of course, specify them again using something like a ComponentListener.

However... there's a better way. Swing has a concept of a LayoutManager that does all this work for you!

Some of the different layout managers do a better job than others, personally, I find GroupLayout to be the most robust when dealing with the specific problem of resizing windows.

tl;dr So, remember, don't specify the sizes using .setSize() and don't specify the locations using setLocation(), use a LayoutManager.

durron597
  • 31,968
  • 17
  • 99
  • 158