2014-10-19 1 views
0

그래서 Path2D 원을 JPanel에 그립니다. 사용자가 원의 오른쪽 하단을 클릭하여 끌 때 원의 크기를 조정하려고합니다. 그래서, 내가 원했던 것은 동그라미의 바깥 쪽 오른쪽 하단이 아닌 오른쪽 에있을 때를 감지하는 것입니다. 주위의 경계선의 오른쪽 하단이 아닙니다.JPanel에서 Path2D 원의 바깥 쪽 가장자리를 감지 함

enter image description here

내가 사각형 (도로 getBounds 사용)하지만 원에 도로 getBounds()를 사용하는 경우, 그것은을 반환하여이 작업을 수행하는 방법을 알고 : 기본적으로,이 같은 작업을 수행하는 방법을 강구해야 실제 원의 범위가 아니라 원 주위를 사각형으로 표시합니다. 이 일을 어떻게 얻을 수 있는지에 대한 아이디어가 있습니까? 감사! 여기

내 프로그램의 단축, 실행 가능한 버전입니다 :

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Panel; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Path2D; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Editor { 

    public static void main(String[] args) { 

     JFrame frame = new UMLWindow(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setBounds(30, 30, 1000, 700); 
     frame.getContentPane().setBackground(Color.white); 
     frame.setVisible(true); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

class UMLWindow extends JFrame { 
    Shapes shapeList = new Shapes(); 
    Panel panel; 

    private static final long serialVersionUID = 1L; 

    public UMLWindow() { 
     addMenus(); 
     panel = new Panel(); 
    } 

    public void addMenus() { 

     getContentPane().add(shapeList); 

     setSize(300, 200); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     shapeList.addCircle(100, 100); 
    } 
} 

// Shapes class, used to draw the shapes on the panel 
// as well as implements the MouseListener for dragging 
class Shapes extends JPanel { 
    private static final long serialVersionUID = 1L; 

    private List<Path2D> shapes = new ArrayList<Path2D>(); 
    int currentIndex; 

    public Shapes() { 
     MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
     addMouseListener(myMouseAdapter); 
     addMouseMotionListener(myMouseAdapter); 
    } 

    public void addCircle(int width, int height) { 
     Path2D circ = new Path2D.Double(); 
     circ.append(new Ellipse2D.Double(442, 269, width, height), true); 
     shapes.add(circ); 
     repaint(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2 = (Graphics2D) g; 
     g2.setStroke(new BasicStroke(2)); 
     for (Path2D shape : shapes) { 
      g2.draw(shape); 
     } 
    } 

    class MyMouseAdapter extends MouseAdapter { 

     @Override 
     public void mousePressed(MouseEvent e) { 

     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
     } 
    } 
} 
+0

아마도 삼각뿔을 사용하고 싶을 수도 있지만 PathIterator @ – MadProgrammer

+0

@MadProgrammer 나는 trig을 사용하지 말라고 말하지 않았 으면 좋겠다. – Harry

답변

2

당신은 삼각법 (또는 내가했던 것처럼 Google 검색;))을 브러시로 처리하고 싶을 것입니다. 기본 개념은 "상대적으로"쉽게,하지만 난이 주어진 X/Y 점을 계산합니다 나를 위해 모든 일에 좋은 방법 ...

이 방법 ...

public Point2D getPointOnEdge(float angel, Rectangle bounds) { 

    float radius = Math.max(bounds.width, bounds.height)/2; 

    float x = radius; 
    float y = radius; 

    double rads = Math.toRadians((angel + 90)); 

    // Calculate the outter point of the line 
    float xPosy = (float) (x + Math.cos(rads) * radius); 
    float yPosy = (float) (y + Math.sin(rads) * radius); 

    return new Point2D.Float(xPosy + bounds.x, yPosy + bounds.y); 

} 

을 생성 각도가 원에 표시됩니다. 기억하세요. 이것은 서클에서만 작동합니다. 그때 다른 방법을 사용

...

public Rectangle2D getActiveBounds(float angel, Rectangle bounds) { 

    Point2D p = getPointOnEdge(angel, bounds); 

    return new Rectangle2D.Double(p.getX() - 4, p.getY() - 4, 8, 8); 

} 

내가 하단/우측 영역으로 고려할 것입니다있는 "마우스 영역을"계산하려면, 하나의 픽셀이 찾아 간단하게 사용하기 어려운 원인 그것을 현재 마우스 위치를 전달 Rectangle#contains, ...

Mouse Hover

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Panel; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Path2D; 
import java.awt.geom.Point2D; 
import java.awt.geom.Rectangle2D; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import static javax.swing.JFrame.EXIT_ON_CLOSE; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Editor { 

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

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

       JFrame frame = new UMLWindow(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setBounds(30, 30, 1000, 700); 
       frame.getContentPane().setBackground(Color.white); 
       frame.setVisible(true); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static class UMLWindow extends JFrame { 

     Shapes shapeList = new Shapes(); 
     Panel panel; 

     private static final long serialVersionUID = 1L; 

     public UMLWindow() { 
      addMenus(); 
      panel = new Panel(); 
     } 

     public void addMenus() { 

      getContentPane().add(shapeList); 

      setSize(300, 200); 
      setLocationRelativeTo(null); 
      setDefaultCloseOperation(EXIT_ON_CLOSE); 

      shapeList.addCircle(100, 100); 
     } 
    } 

// Shapes class, used to draw the shapes on the panel 
// as well as implements the MouseListener for dragging 
    public static class Shapes extends JPanel { 

     private static final long serialVersionUID = 1L; 

     private List<Path2D> shapes = new ArrayList<Path2D>(); 
     int currentIndex; 

     private Point mousePoint; 

     public Shapes() { 
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
      addMouseListener(myMouseAdapter); 
      addMouseMotionListener(myMouseAdapter); 
     } 

     public void addCircle(int width, int height) { 
      Path2D circ = new Path2D.Double(); 
      circ.append(new Ellipse2D.Double(442, 269, width, height), true); 
      shapes.add(circ); 
      repaint(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      Graphics2D g2 = (Graphics2D) g; 
      g2.setStroke(new BasicStroke(2)); 
      for (Path2D shape : shapes) { 
       g2.setColor(Color.BLACK); 
       g2.draw(shape); 

       g2.setColor(Color.RED); 
       Rectangle2D bottomRight = getActiveBounds(-45, shape.getBounds()); 

       g2.draw(bottomRight); 
       if (mousePoint != null) { 

        if (bottomRight.contains(mousePoint)) { 
         g2.fill(bottomRight); 
        } 

       } 

      } 
     } 

     public Rectangle2D getActiveBounds(float angel, Rectangle bounds) { 

      Point2D p = getPointOnEdge(angel, bounds); 

      return new Rectangle2D.Double(p.getX() - 4, p.getY() - 4, 8, 8); 

     } 

     public Point2D getPointOnEdge(float angel, Rectangle bounds) { 

      float radius = Math.max(bounds.width, bounds.height)/2; 

      float x = radius; 
      float y = radius; 

      double rads = Math.toRadians((angel + 90)); 

      // Calculate the outter point of the line 
      float xPosy = (float) (x + Math.cos(rads) * radius); 
      float yPosy = (float) (y + Math.sin(rads) * radius); 

      return new Point2D.Float(xPosy + bounds.x, yPosy + bounds.y); 

     } 

     class MyMouseAdapter extends MouseAdapter { 

      @Override 
      public void mouseMoved(MouseEvent e) { 
       mousePoint = e.getPoint(); 
       repaint(); 
      } 

     } 
    } 

} 

이 예는 paint 메소드 내의 모든 작업 일 수 않습니다 "효과의 영역"을보고 싶었 기 때문에 동일한 논리를 사용하여 마우스 커서를 쉽게 변경할 수 있습니다. MouseMoitionListener

2

확실하지 않음이 작동하지만 당신은 같은 것을 시도 할 경우 다음의 몇 가지 인 모양의 원을 만들기

  1. 을 원래 모양보다 작은 픽셀
  2. 원래 모양보다 몇 픽셀 크기가 큰 모양 원형을 만듭니다.
  3. 큰 S를 사용하여 영역 개체를 만듭니다 hape
  4. 작은 도형을 사용하여 Area 객체를 만들고 더 큰 영역에서이 영역을 뺍니다.
  5. contains (...) 메소드를 사용하여 마우스 포인트가이 영역 내에 있는지 확인합니다.
+0

* "작동하지 않을지 확실하지 않습니다."* PathIterator를 체크 아웃 할 것입니다. * * 작동 할 것입니다 *. –

+0

@AndrewThompson, 자신감의 투표에 감사드립니다 :) – camickr