2013-06-25 3 views
0

그래서 두 가지 JFrames를 작성하고 싶습니다. 하나는 전체 화면을 덮고 사용자가 해당 화면을 클릭하면 사용자가 마우스를 클릭하여 끌 때 새로운 JFrame이 나타납니다. 사용자가 처음으로 클릭하는 위치는 새 JFrame의 왼쪽 위 모서리이며 사용자가 마우스를 놓은 곳은 JFrame의 오른쪽 하단입니다. 마우스를 클릭하여 놓을 때 두 개의 JFrame을 만들고 두 번째 JFrame을 표시하는 데 아무런 문제가 없습니다. 문제는 마우스를 놓기 전에 사용자가 마우스를 움직일 때 새로운 JFrame을 실시간으로 보여주고 싶습니다. 시도했지만변경시 실시간으로 JFrame 표시

public void mouseDragged(MouseEvent e) { 

      FrontWindow f = new FrontWindow(); 

      while (true) {   
       f.setBounds(Shared.xPressed, Shared.yPressed, (Utils.getXPosition() - Shared.xPressed) , (Utils.getYPosition() - Shared.yPressed)); 
       f.setVisible(true); 
      } 

     } 

하지만 작동하지 않았습니다.

+0

JFrame 자체가 나타나기를 원하십니까? 아니면 개요가 충분합니까? –

+2

차단 된 Event Dispatching Thread의 멋진 세계에 오신 것을 환영합니다. 귀하의 코드는 귀하의 응용 프로그램이 새로운 이벤트를 처리하는 것을 막을뿐만 아니라 어떠한 업데이트/다시 그리기도 수행하지 못하도록합니다. – MadProgrammer

+0

@MonadNewb 마우스로 모양이 변경되는 한 JFrame의 윤곽으로 충분합니다 움직입니다. – Maple

답변

4

while 루프가 필요하지 않습니다. 여러 개의 mouseDragged() 이벤트가 생성됩니다.

mousePressed() 이벤트에 새 프레임을 만들어야합니다. 그런 다음 각 mouseDragged() 이벤트가 생성 될 때 프레임 크기를 변경합니다.

드래그하는 것이 프레임의 크기와 일치하지 않기 때문에 물론 이것은 좋지 않을 것입니다. 더 나은 방법은 마우스를 움직일 때 직사각형을 그리는 것입니다. 그런 다음 mouseReleased에서 그려진 사각형의 크기로 프레임을 만들고 표시합니다.

마우스로 직사각형을 그리는 기본 사항은 Custom Paint Approaches을 참조하십시오. 귀하의 경우 마우스 페널을 사용하여 마우스 이벤트를 처리하고 사각형을 그릴 수 있습니다.

+1

나는 실례를 당신에게 제공했다. 두 예제 모두 Rectangle을 동적으로 그립니다. mouseReleased에서 사각형을 저장합니다. Rectangle을 저장하는 대신 Rectangle의 현재 범위를 사용하여 프레임을 만들 것입니다. 코드를보고 시도한 다음 질문하십시오. – camickr

2

while (true)mouseDragged() 이벤트 핸들러에서 Swing의 EDT (Event Dispatcher Thread)를 차단합니다. 이는 프로그램이 추가 이벤트를 수신하지 않음을 의미합니다. 따라서 사용자가 마우스를 처음 드래그하면이 무한 루프가 시작됩니다. 그러나 운영 체제는 사용자가 마우스를 드래그 할 때 마우스가 계속 움직 였다는 사실을 사용자가 알지 못하도록 알려주지 못합니다.

0

SwingUtilities.invokeLater()를 사용하여 별도의 스레드에서 MouseInfo.getPointerInfo().getLocation()를 실행 해보십시오 :

SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     Point mp = MouseInfo.getPointerInfo().getLocation(); 
     f.setBounds(Shared.xPress, Shared.yPress, mp.x - Shared.xPress, mp.y - Shared.yPressed); 
    } 
} 
0

스윙은 단일 스레드 프레임 워크입니다. 즉, 단일 스레드를 사용하여 이벤트를 모든 관련 당사자에게 전달합니다.

스레드가이 스레드를 차단하면 (예 : 무한대 while-loop) 스레드는 다시 그리기 요청을 포함하여 응용 프로그램에 들어오는 새로운 이벤트를 처리 할 수 ​​없습니다. 이것은 응용 프로그램을 매달아 놓은 것처럼 보이게 할 것입니다 (귀하의 경우 실제로 있음).

자세한 내용은 Concurrency in Swing을 참조하십시오.

다음 예제에서는 창의 표면을 클릭/드래그하여 드래그 과정을 나타내는 사각형을 렌더링합니다.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class DrawRectangle { 

    public static void main(String[] args) { 
     new DrawRectangle(); 
    } 

    public DrawRectangle() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Rectangle dragRect; 

     public TestPane() { 

      MouseHandler handler = new MouseHandler(); 
      addMouseListener(handler); 
      addMouseMotionListener(handler); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      if (dragRect != null) { 
       g2d.setColor(Color.DARK_GRAY); 
       g2d.draw(dragRect); 
      } 
      g2d.dispose(); 
     } 

     public class MouseHandler extends MouseAdapter { 

      private Point clicked; 

      @Override 
      public void mousePressed(MouseEvent e) { 
       clicked = e.getPoint(); 
      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
      } 

      @Override 
      public void mouseDragged(MouseEvent e) { 

       Point p = e.getPoint(); 

       int x = Math.min(p.x, clicked.x); 
       int y = Math.min(p.y, clicked.y); 

       int width = Math.max(p.x, clicked.x) - x; 
       int height = Math.max(p.y, clicked.y) - y; 

       dragRect = new Rectangle(x, y, width, height); 
       repaint(); 

      } 

     } 

    } 
} 
+0

고맙습니다. 대신 정사각형을 그리는 아이디어에 대해 다른 사용자에게 감사드립니다. 코드를보고 프로그램과 함께 추가하십시오. – Maple

관련 문제