2010-01-21 61 views
29

当用户单击JFrame的角落以调整大小并拖动鼠标时,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"); 
    } 
} 

如何确定并限制用户如何调整其大小的窗口(基于窗口的当前长宽比),因为他们周围拖动鼠标周围?

+0

@finnw请你澄清你的赏金理由,因为我看到'Java_1.4'和'Java_1.5'之间的区别,但是我找不到'Java_6','note'的区别,但是没有最深的检查到嵌套和继承方法 – mKorbel 2011-10-06 08:53:39

+0

@mKorbel,我尝试了两种方法(JPanel上的ComponentListener;覆盖验证)。代码编译并在两个版本的Java下运行,但在Java 1.6中,布局不断被重新计算,但是在Java 1.5只有当我释放鼠标。 – finnw 2011-10-06 12:17:35

+0

@finnw你调整JComponent或JFrame – mKorbel 2011-10-06 12:23:40

回答

7

你可能需要重写像validate(不要忘记调用超级)。当然,如果您使用窗口系统配置为拖动轮廓线,这仍然可能不起作用。

+0

我怎么会叫我认为你只能在构造函数中调用超级域名? – 2011-06-09 16:55:37

+3

哎呀,找到它了。super.validate(),当然。 – 2011-06-09 17:00:12

37

您可以添加组件侦听器,并实现这样的功能的componentResized:

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

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

编辑:显然,对于JFrame的,上的componentResized事件被挂在事件的mouseReleased。这就是为什么当释放鼠标按钮时调用该方法的原因。

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

我知道,这不是最优雅的解决方案,但它的工作原理!

+0

感谢您的及时响应。但是,componentResized仅在用户释放鼠标按钮时才会调用。是否有可能听到调整事件大小*为用户拖动鼠标? – Clinton 2010-01-21 01:50:44

+0

@Clinton真的!对不起,我没有仔细阅读你的问题! – Alex 2010-01-21 01:56:02

+0

@Clinton我很好奇这是如何完成的,我发现的唯一方法是在JFrame中添加一个JPanel。我不知道这是否有助于你。我已经更新了我的答案。 – Alex 2010-01-21 03:03:08

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

} 
+2

-1。这基本上是问题中的代码的副本(我们已经知道并不能解决问题。) – finnw 2011-10-12 11:07:50

6

另一个解决方法(这是非常相似,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"); 
      } 
     }); 
    } 
} 

根据其他实施细节,可能会改变根窗格。如果这是可能性,那么你可以覆盖setRootPane()并处理。由于setRootPane()受保护,只能从构造函数调用,所以不太可能需要这样做。

+0

不应该是'public void TestFrame(){'...? – 2014-01-05 02:53:43

+2

@AnnonomusPenguin,不,这是一个构造函数声明,而构造函数不指定返回类型,如'void'。 – 2014-08-10 01:50:43