2012-02-20 3 views
3

그래서 기본적으로 사용자가 원하는 크기로 마우스를 클릭하고 드래그하여 JComboBox의 선택 항목을 기반으로 사각형을 채우는 프로그램을 작성하고 있습니다. 내가 구현 한 어떤Canvas를 사용하여 사용자 입력을 기반으로 여러 사각형을 그리는 방법?

basic layout

은의 MouseListener와 모든 MouseMotionListener 사용자가 처음 곳으로가 보자하고 이동을 클릭 한 위치에 따라 사각형을 마우스의 위치를 ​​추적하고, 그릴 것입니다.

사용자가 클릭하고 드래그하면 (이동은 허용되지 않음) drawRect()는 있지만 fillRect()는 없습니다 (사각형이 채워지지 않음 - 사용자가 마우스를 놓을 때만 사각형을 수행 함). 색상으로 채우기).

이 클래스는 생성자에서 선택된 색상 (아래의 ColorListener 클래스에서 결정됨) 인 Rect 객체를 만듭니다.

이 내 인스턴스 변수를 포함 곳이며, 모든 것이 아래의 생성자에서 인스턴스화 :

private ArrayList<Rect> rectList; 
private Color currentColor; 
private Canvas canvas; 
private JPanel controlPanel; 
private JButton undo, erase; 
private JComboBox comboBox; 
private int xStart, yStart, xEnd, yEnd; 
private Graphics page; 
private Point pt = null; 
private PointListener pointListener; 
private ColorListener colorListener; 

public WholePanel() 
{ 
    // here we use black to draw a rectangle 
    currentColor = Color.black; 
    pointListener = new PointListener(); 
    addMouseListener(pointListener); 
    addMouseMotionListener(pointListener); 

    String[] listOfColors = {"black", "red", "blue", "green", "orange"}; 

    comboBox = new JComboBox(listOfColors); 
    comboBox.setSelectedIndex(0); 

    rectList = new ArrayList<Rect>(); 
    controlPanel = new JPanel(new GridLayout(1,3)); 

    undo = new JButton("Undo"); 
    erase = new JButton("Erase"); 
    controlPanel.add(comboBox); 
    controlPanel.add(undo); 
    controlPanel.add(erase); 
    undo.addActionListener(new ButtonListener()); 
    erase.addActionListener(new ButtonListener()); 

    canvas = new Canvas(); 

    JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, controlPanel, canvas); 

    setLayout(new BorderLayout()); 
    add(sp); 
} 

사각형 클래스는 나중에 사용되는 사각형 개체를 만들 수 있습니다.

public class Rect 
{ 
private int x1, y1, width1, height1; 
private Color color1; 

public Rect(int x, int y, int width, int height, Color color) 
{ 
    x1 = x; 
    y1 = y; 
    width1 = width; 
    height1 = height; 
    color1 = color; 
} 

public void draw(Graphics page) 
{ 
    page.setColor(color1); 
    page.drawRect(x1,y1,width1,height1); 
} 
} 

Canvas 클래스는 개체 그리기를 허용하는 공간을 만듭니다.

private class Canvas extends JPanel 
{ 

    public void paintComponent(Graphics page) 
    { 
     super.paintComponent(page); 
     setBackground(Color.white); 
     if (pt != null) 
     { 
      Rect rect = new Rect(xStart, yStart, xEnd-xStart, yEnd-yStart, currentColor); 
      rect.draw(page); 
     } 
    } 
} 

PointListener 클래스는 같이있을 수있는 모든 점을 발견 한 경우 사용자가 클릭에 사용자가, 또한 여기서 사용자 릴리스 드래그 곳.

private class PointListener implements MouseListener, MouseMotionListener 
{ 
    public void mousePressed(MouseEvent event) 
    { 
     pt = event.getPoint(); 
     xStart = pt.x; 
     yStart = pt.y; 
    } 
    public void mouseReleased(MouseEvent event) 
    { 
     pt = event.getPoint(); 
     if (pt != null) 
     { 
      xEnd = pt.x; 
      yEnd = pt.y; 
      page.fillRect(xStart, yStart, xEnd-xStart, yEnd-yStart); 
     } 
    } 
    public void mouseClicked(MouseEvent event) {} 
    public void mouseEntered(MouseEvent event) {} 
    public void mouseExited(MouseEvent event) {} 
    public void mouseDragged(MouseEvent event) 
    { 
     pt = event.getPoint(); 
     if (pt != null) 
     { 
      xEnd = pt.x; 
      yEnd = pt.y; 
      Rect rect = new Rect(xStart, yStart, xEnd-xStart, yEnd-yStart, currentColor); 
      rect.draw(page); 
     } 
     repaint(); 
    } 
    public void mouseMoved(MouseEvent event) {} 

} 

는 ColorListener는 main() 메소드에서 판정을 JComboBox에서 선택된 개체 유형을 발견하고, 그것에 CurrentColor에 (그 위에 사각형 생성자 컬러로 다시 넣어)를 설정한다.

private class ColorListener implements ActionListener 
{ 
    public void actionPerformed(ActionEvent event) 
    { 
     if (event.getSource().equals("black")) 
     { 
      currentColor = Color.black; 
      comboBox.setSelectedIndex(0); 
     } 
     else if (event.getSource().equals("red")) 
     { 
      currentColor = Color.red; 
      comboBox.setSelectedIndex(1); 
     } 
     else if (event.getSource().equals("blue")) 
     { 
      currentColor = Color.blue; 
      comboBox.setSelectedIndex(2); 
     } 
     else if (event.getSource().equals("green")) 
     { 
      currentColor = Color.green; 
      comboBox.setSelectedIndex(3); 
     } 
     else if (event.getSource().equals("orange")) 
     { 
      currentColor = Color.orange; 
      comboBox.setSelectedIndex(4); 
     } 
    } 
} 

그래서 내가 그리는 데 어려움이 있습니다. 지금까지는 프로그램의 논리에 어떤 결함도 보이지 않았고, Canvas에 그릴 수있는 것은 아무것도 없었습니다 (JButtons Undo and Erase에 대해 걱정하지 마십시오. ArrayList와 함께 사용하기 쉽고 remove() 및 clear() 및 이와 유사한 항목).

+0

이전에 선언 한 인스턴스 변수 인 WholePanel이라는 전체 클래스의 생성자에서 인스턴스화되었습니다 (두 번째로 추가 할 예정입니다). –

답변

2

프로그램에는 클래스 필드 (페이지 클래스 필드) 인 그래픽 필드가 없어야합니다. 대신 그래픽 객체가 JVM에서만 얻을 수 있어야

public void mouseReleased(MouseEvent event) 
{ 
    pt = event.getPoint(); 
    if (pt != null) 
    { 
     xEnd = pt.x; 
     yEnd = pt.y; 


     // !!!! don't do this !!!! 
     page.fillRect(xStart, yStart, xEnd-xStart, yEnd-yStart); 
    } 
} 

,해야 만 내 존재 : 당신은 당신이 위의 사용에 마우스 리스너 클래스는 말을 시도하고있는 방법과 NullPointException가 표시되지 놀랐어요 이 메소드는 paintComponent 메소드와 같은 paintComponent 메소드 내에서만 사용되어야합니다 (이 오브젝트에 건네지는 paintComponent로부터 불려 간 메소드는 물론, BufferedImage로부터 취득한 Graphics 오브젝트). MouseListener/MouseMotionListener는 mouseDragged 동안 x-start, y-start, x-end 및 y-end 변수를 채운 다음 mouseRelease에서 rectList에 배치 된 새 Rect 객체를 만드는 데 사용해야합니다. 그런 다음 다시 칠해.

그런 다음 paintComponent는 rectList를 반복하여 그곳에서 찾은 각 Rect 객체를 채워야합니다.

+0

나는 아직도 그들이 그림을 그리지 않는 이유에 대해 혼란 스럽다. mousePressed가 포인트를 얻어야하고, x-coord를 xStart로, y-coord를 yStart로 설정해야한다. 그렇지 않으면 mouseDragged가 얻어야한다. 4 점 모두 (그 둘과 xEnd와 yEnd)? –

+0

나는 논리와 물건에 여전히 잘못된 것이 무엇인지 혼란스러워합니다. –

+0

[sscce] (http://sscce.org)를 게시 할 수 있습니까? –

관련 문제