java - 我可以将 Swing 对象设置为与其底层容器的大小成比例吗?

标签 java swing graphics

我可以采用我实例化的 MyHouse 对象之一,并以某种方式将其设置为与其底层 NscComponent 容器按比例缩放吗?

当我使用从 NscComponent 继承的 setSize 方法时,它不会更改 house1 MyHouse 对象的大小。它使容器变小,但对象不变,并且容器调整大小并剪掉大部分 house1 对象。我尝试在 MyHouse.java 中创建一个新方法,调整组成整个房子的每个 MyHouse 组件的大小,这很有效,但随后坐标全部搞砸了,房子本身看起来就像全部 splinter 了。

似乎必须操作 MyHouse 对象的每个单独组件来调整大小,这违背了创建对象的全部意义。

这是MyHouse代码:

/**
 * 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();
  } 

}

这里是 MyScene 代码,它实例化 3 个 MyHouse 对象并将它们放入场景中。

// 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();
  }

}

最佳答案

您的问题是您正在手动指定每个组件的大小。当然,如果您手动指定事物的大小和位置,那么重新计算它们将是一个巨大的痛苦!当然,您必须使用 ComponentListener 之类的东西再次指定它们。

但是...还有更好的方法。 Swing 有一个 LayoutManager 的概念这一切都为您完成!

我个人认为,一些不同的布局管理器比其他布局管理器做得更好 GroupLayout在处理调整窗口大小的具体问题时是最强大的。

tl;dr 因此,请记住,不要使用 .setSize() 指定尺寸,也不要使用 setLocation() 指定位置,而应使用 LayoutManager

关于java - 我可以将 Swing 对象设置为与其底层容器的大小成比例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31492843/

相关文章:

R:独立于缩放旋转文本(使用多行文本)?

java - Spring:为什么我在使用注解时需要applicationContext.xml?

java - 这种显示图像的方法有什么问题?

java - 最大化窗口和布局 channel

java - "The method addActionListener(ActionListener) in the type AbstractButton is not applicable for the arguments"错误

java - Swing:简单应用程序的布局和组件选择

java - 为什么调用 "repaint()"而不是在Applet中直接调用 "paint(..)"?

php - 寻找用于交互式网络对象演示的 PHP/Flash 图形库

java - 在 pl/sql 中将关联数组传递给 java

java - wait后线程恢复(if-else的作用)