Escuchar JFrame redimensionar eventos como el usuario arrastra su ratón?


Cuando un usuario hace clic en la esquina de un JFrame para cambiar el tamaño y arrastra el ratón, el JFrame redibuja según la posición actual del ratón a medida que el usuario arrastra. ¿Cómo puedes escuchar estos eventos?

A continuación se muestra lo que he intentado actualmente:

public final class TestFrame extends JFrame {
    public TestFrame() {
        this.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                // This is only called when the user releases the mouse button.
                System.out.println("componentResized");
            }
        });
    }

    // These methods do not appear to be called at all when a JFrame
    // is being resized.
    @Override
    public void setSize(int width, int height) {
        System.out.println("setSize");
    }

    @Override
    public void setBounds(Rectangle r) {
        System.out.println("setBounds A");
    }

    @Override
    public void setBounds(int x, int y, int width, int height) {
        System.out.println("setBounds B");
    }
}

¿Cómo puedo determinar y restringir cómo el usuario cambia el tamaño de una ventana (basado en la relación de aspecto actual de la ventana) mientras arrastra alrededor del mouse?

Author: Clinton, 2010-01-21

4 answers

Probablemente necesites anular algo como validate (no olvides llamar al super). Por supuesto, eso todavía puede no funcionar si está utilizando un sistema de ventanas configurado para arrastrar contornos.

 7
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-21 01:59:53

Puede agregar un oyente de componentes e implementar la función componentResized así:

JFrame component = new JFrame("My Frame");

component.addComponentListener(new ComponentAdapter() 
{  
        public void componentResized(ComponentEvent evt) {
            Component c = (Component)evt.getSource();
            //........
        }
});

EDITAR: Aparentemente, para JFrame, el evento componentResized está enganchado al evento mouseReleased. Es por eso que el método se invoca cuando se suelta el botón del ratón.

Una forma de lograr lo que quieres, es agregar un JPanel que cubra toda el área de tu JFrame. Luego agregue el ComponentListener al JPanel (componentResized para JPanel se llama incluso mientras su ratón todavía está arrastrando). Cuando se redimensiona el marco, también se redimensionará el panel.

Lo sé, esta no es la solución más elegante, pero funciona!

 38
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-11 23:25:17

Otra solución (que es muy similar a la de Alex, pero un poco más sencilla) es escuchar los eventos desde el panel raíz de JFrame:

public final class TestFrame extends JFrame {
    public TestFrame() {
        this.getRootPane().addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                // This is only called when the user releases the mouse button.
                System.out.println("componentResized");
            }
        });
    }
}

Dependiendo de otros detalles de implementación, es posible que se cambie el panel raíz. Si esa es una posibilidad, entonces podría anular setRootPane() y lidiar con eso. Dado que setRootPane() está protegido y solo se llama desde el constructor, es poco probable que tenga que hacer eso.

 6
Author: vaughandroid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-12 13:51:16
public class MouseDrag extends Component implements MouseListener,
    MouseMotionListener {
  /** The Image we are to paint */
  Image curImage;

  /** Kludge for showStatus */
  static Label status;

  /** true if we are in drag */
  boolean inDrag = false;

  /** starting location of a drag */
  int startX = -1, startY = -1;

  /** current location of a drag */
  int curX = -1, curY = -1;

  // "main" method
  public static void main(String[] av) {
    JFrame f = new JFrame("Mouse Dragger");
    Container cp = f.getContentPane();

    if (av.length < 1) {
      System.err.println("Usage: MouseDrag imagefile");
      System.exit(1);
    }
    Image im = Toolkit.getDefaultToolkit().getImage(av[0]);

    // create a MouseDrag object
    MouseDrag j = new MouseDrag(im);

    cp.setLayout(new BorderLayout());
    cp.add(BorderLayout.NORTH, new Label(
        "Hello, and welcome to the world of Java"));
    cp.add(BorderLayout.CENTER, j);
    cp.add(BorderLayout.SOUTH, status = new Label());
    status.setSize(f.getSize().width, status.getSize().height);
    f.pack();
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  // "Constructor" - creates the object
  public MouseDrag(Image i) {
    super();
    curImage = i;
    setSize(300, 200);
    addMouseListener(this);
    addMouseMotionListener(this);
  }

  public void showStatus(String s) {
    status.setText(s);
  }

  // Five methods from MouseListener:
  /** Called when the mouse has been clicked on a component. */
  public void mouseClicked(MouseEvent e) {
  }

  /** Called when the mouse enters a component. */
  public void mouseEntered(MouseEvent e) {
  }

  /** Called when the mouse exits a component. */
  public void mouseExited(MouseEvent e) {
  }


  // And two methods from MouseMotionListener:
  public void mouseDragged(MouseEvent e) {
    Point p = e.getPoint();
    // System.err.println("mouse drag to " + p);
    showStatus("mouse Dragged to " + p);
    curX = p.x;
    curY = p.y;
    if (inDrag) {
      repaint();
    }
  }

  public void paint(Graphics g) {
    int w = curX - startX, h = curY - startY;
    Dimension d = getSize();
    g.drawImage(curImage, 0, 0, d.width, d.height, this);
    if (startX < 0 || startY < 0)
      return;
    System.err.println("paint:drawRect @[" + startX + "," + startY
        + "] size " + w + "x" + h);
    g.setColor(Color.red);
    g.fillRect(startX, startY, w, h);
  }

}
 -2
Author: Pyadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-12 23:34:11