简体   繁体   English

在用户拖动鼠标时收听 JFrame 调整大小事件?

[英]Listen to JFrame resize events as the user drags their mouse?

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.当用户单击 JFrame 的角以调整大小并拖动鼠标时,JFrame 在用户拖动时根据鼠标的当前位置重绘。 How can you listen to these events?你怎么能听到这些事件?

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?当用户在鼠标周围拖动时,如何确定和限制用户如何调整窗口大小(基于窗口的当前纵横比)?

You can add a component listener and implement the componentResized function like that:您可以添加一个组件侦听器并像这样实现 componentResized 函数:

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.编辑:显然,对于 JFrame,componentResized 事件与 mouseReleased 事件挂钩。 That's why the method is invoked when the mouse button is released.这就是释放鼠标按钮时调用该方法的原因。

One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame.实现您想要的一种方法是添加一个 JPanel,它将覆盖您的 JFrame 的整个区域。 Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging).然后将 componentListener 添加到 JPanel(即使您的鼠标仍在拖动,也会调用 JPanel 的 componentResized)。 When your frame is resized, your panel will also be resized too.当您的框架调整大小时,您的面板也将调整大小。

I know, this isn't the most elegant solution, but it works!我知道,这不是最优雅的解决方案,但它有效!

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.如果这是一种可能性,那么您可以覆盖setRootPane()并处理它。 Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.由于setRootPane()是受保护的,并且只能从构造函数中调用,因此您不太可能需要这样做。

You probably need to override something like validate (don't forget to call the super).您可能需要覆盖诸如validate之类的东西(不要忘记调用 super)。 Of course, that still may not work if you are using a windowing system to configured to drag outlines.当然,如果您使用窗口系统配置为拖动轮廓,这仍然可能不起作用。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JavaFX-通知用户何时将鼠标从一个节点拖到另一个节点? - JavaFX - Notify when user drags mouse from one Node to another? 使用鼠标调整无边框的JFrame的大小 - Resize a JFrame, which has no border, using a mouse 当用户拖动调整舞台窗口大小时,如何让JavaFX节点(textarea,textfield)正确调整大小? - How to get JavaFX nodes (textarea, textfield) to resize correctly when user drags to resize the stage window? 听取整个系统的鼠标点击(不是在JFrame等上) - Listen to mouse clicks on whole system (not on a JFrame etc.) 仅在释放鼠标时捕获 JFrame 调整大小一次 - Capture JFrame resize only once, when mouse is released Java swing:哪个组件处理鼠标事件以调整 JFrame 或 JDialog - Java swing: which component handles the mouse event to resize a JFrame or JDialog 如何将半透明JWindow上的鼠标事件传递到下面的JFrame? - How can I pass mouse events on a translucent JWindow to the JFrame underneath? 如何使用JPanel和Jframe在相对(X,Y)上进行鼠标事件 - how to make mouse events on (X,Y) relative using JPanel and Jframe 如何捕获JFrame / Swing中的所有鼠标事件? - How can I capture all mouse events in a JFrame/Swing? SWT - 如何监听鼠标事件,并检索其绝对位置? - SWT - how to listen for mouse events, and retrieve their absolute position?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM