当用户拖拽鼠标时,监听JFrame调整事件大小?

时间:2021-11-01 00:00:16

When a user clicks on the corner of a JFrame to resize and drags the mouse around, the JFrame redraws based on the current position of the mouse as the user drags. How can you listen to these events?

当用户单击JFrame的一角以调整鼠标大小并拖动鼠标时,JFrame会根据用户拖动鼠标的当前位置重新绘制。你怎么能听这些事情?

Below is the what I have currently tried:

以下是我目前尝试的:

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

How can I determine and constrain how the user resizes a window (based on the current aspect ratio of the window) as they are dragging around the mouse around?

我如何确定和限制用户在鼠标周围拖动时如何调整窗口的大小(基于当前窗口的长宽比)?

4 个解决方案

#1


7  

You probably need to override something like validate (don't forget to call the super). Of course, that still may not work if you are using a windowing system to configured to drag outlines.

您可能需要覆盖诸如validate(不要忘记调用super)之类的内容。当然,如果您正在使用一个窗口系统来配置为拖动轮廓,那么这仍然可能不工作。

#2


37  

You can add a component listener and implement the componentResized function like that:

您可以添加一个组件侦听器并实现组件调整大小的函数,如下所示:

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

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

EDIT: Apparently, for JFrame, the componentResized event is hooked to the mouseReleased event. That's why the method is invoked when the mouse button is released.

编辑:显然,对于JFrame,组件大小的事件与鼠标悬空事件相关联。这就是为什么在释放鼠标按钮时调用该方法的原因。

One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame. Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging). When your frame is resized, your panel will also be resized too.

实现所需的一种方法是添加一个JPanel,它将覆盖JFrame的整个区域。然后将componentListener添加到JPanel(即使在您的鼠标仍在拖动时,JPanel的componentResized也会被调用)。当你的帧被调整大小时,你的面板也会被调整大。

I know, this isn't the most elegant solution, but it works!

我知道,这不是最优雅的解决方案,但它确实有效!

#3


6  

Another workaround (which is very similar to Alex's but a little more straightforward) is to listen to the events from the JFrame's root pane instead:

另一个解决方案(非常类似于Alex的方法,但更直接一点)是从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");
            }
        });
    }
}

Depending on other implementation details, it's possible that the root pane might be changed. If that's a possibility then you could override setRootPane() and deal with that. Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.

根据其他实现细节,可能会更改根窗格。如果有这种可能性,那么可以重写setRootPane()并处理它。由于setRootPane()是受保护的,并且只从构造函数调用,所以不太可能需要这样做。

#4


-2  

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

}

#1


7  

You probably need to override something like validate (don't forget to call the super). Of course, that still may not work if you are using a windowing system to configured to drag outlines.

您可能需要覆盖诸如validate(不要忘记调用super)之类的内容。当然,如果您正在使用一个窗口系统来配置为拖动轮廓,那么这仍然可能不工作。

#2


37  

You can add a component listener and implement the componentResized function like that:

您可以添加一个组件侦听器并实现组件调整大小的函数,如下所示:

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

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

EDIT: Apparently, for JFrame, the componentResized event is hooked to the mouseReleased event. That's why the method is invoked when the mouse button is released.

编辑:显然,对于JFrame,组件大小的事件与鼠标悬空事件相关联。这就是为什么在释放鼠标按钮时调用该方法的原因。

One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame. Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging). When your frame is resized, your panel will also be resized too.

实现所需的一种方法是添加一个JPanel,它将覆盖JFrame的整个区域。然后将componentListener添加到JPanel(即使在您的鼠标仍在拖动时,JPanel的componentResized也会被调用)。当你的帧被调整大小时,你的面板也会被调整大。

I know, this isn't the most elegant solution, but it works!

我知道,这不是最优雅的解决方案,但它确实有效!

#3


6  

Another workaround (which is very similar to Alex's but a little more straightforward) is to listen to the events from the JFrame's root pane instead:

另一个解决方案(非常类似于Alex的方法,但更直接一点)是从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");
            }
        });
    }
}

Depending on other implementation details, it's possible that the root pane might be changed. If that's a possibility then you could override setRootPane() and deal with that. Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.

根据其他实现细节,可能会更改根窗格。如果有这种可能性,那么可以重写setRootPane()并处理它。由于setRootPane()是受保护的,并且只从构造函数调用,所以不太可能需要这样做。

#4


-2  

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

}