Слушайте события изменения размера JFrame, когда пользователь перетаскивает свою мышь? - PullRequest
30 голосов
/ 21 января 2010

Когда пользователь щелкает по углу JFrame, чтобы изменить его размер, и перетаскивает мышь, JFrame перерисовывается в зависимости от текущего положения мыши по мере его перетаскивания. Как вы можете слушать эти события?

Ниже приведено то, что я сейчас пробовал:

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");
    }
}

Как я могу определить и ограничить, как пользователь изменяет размеры окна (на основе текущего соотношения сторон окна), когда они перемещаются вокруг мыши?

Ответы [ 4 ]

40 голосов
/ 21 января 2010

Вы можете добавить слушатель компонента и реализовать функцию componentResized следующим образом:

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

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

EDIT: Очевидно, для JFrame событие componentResized подключено к событию mouseReleased. Вот почему метод вызывается при отпускании кнопки мыши.

Один из способов добиться того, чего вы хотите, - это добавить JPanel, который будет покрывать всю область вашего JFrame. Затем добавьте componentListener к JPanel (componentResized для JPanel вызывается, даже когда ваша мышь все еще перетаскивает). При изменении размера рамки, ваша панель также будет изменена.

Я знаю, это не самое элегантное решение, но оно работает!

7 голосов
/ 21 января 2010

Возможно, вам нужно переопределить что-то вроде validate (не забудьте вызвать супер). Конечно, это может не сработать, если вы используете систему управления окнами, настроенную для перетаскивания контуров.

6 голосов
/ 12 октября 2011

Другой обходной путь (который очень похож на Алекса, но немного более простой) заключается в прослушивании событий из корневой панели 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");
            }
        });
    }
}

В зависимости от других деталей реализации, возможно, что корневая панель может быть изменена. Если это возможно, тогда вы можете переопределить setRootPane() и справиться с этим. Поскольку setRootPane() защищен и вызывается только из конструктора, маловероятно, что вам понадобится это сделать.

0 голосов
/ 12 октября 2011
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);
  }

}
...