2013-02-10 4 views
0

나는 paint 이벤트가 paint되었을 때 이미지에 선을 그려야하는 프로그램을 작성했지만 paintComponent를 repaint() paintComponent 메소드가 실행되지 않습니다. 스윙 그래픽에 대한 튜토리얼을 읽었으며 다른 프로그래머의 의견도 있었지만 현재까지는 저에게 적합한 솔루션을 찾을 수 없었습니다.paintComponent()가 다시 칠 때 호출되지 않음

본인 및 다른 사람이 내 코드를 검토하기 위해이 프로그램을 단순화하기 위해 예상대로 작동하지 않는 내 프로그램 내에서 코드 영역을 찾아내는 데 도움이되는 작은 SSCCE를 게시했습니다.

시간을내어이 문제를 저에게 보여 주시는 분께 미리 감사드립니다.

아래 두 개의 별도 클래스가 있습니다.

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 

public class TestGraphics { 
private JLayeredPane contentPane; 

public void newImage() { 
    try { 
     JFileChooser fileChooser = new JFileChooser("."); 
     int status = fileChooser.showOpenDialog(null); 

     if (status == JFileChooser.APPROVE_OPTION) { 
      File selectedFile = fileChooser.getSelectedFile(); 
      System.out.println("The selected file is from the: " + selectedFile.getParent() + " Drive"); 
      System.out.println("Name of file: " + selectedFile.getName()); 
      System.out.println("Opening file"); 

      BufferedImage buffImage = ImageIO.read(new File(selectedFile.getAbsolutePath())); 
      ImageIcon image = new ImageIcon(buffImage); 
      JLabel label = new JLabel(image); 
      label.setSize(label.getPreferredSize()); 

      label.setLocation(0, 0); 

      contentPane = new JLayeredPane(); 
      contentPane.setBackground(Color.WHITE); 
      contentPane.setOpaque(true); 
      //getTabbedPane().setComponentAt(tabNum, contentPane); 
      contentPane.add(label); 
      contentPane.setPreferredSize(new Dimension(label.getWidth(), label.getHeight())); 

      Segmentation segmentation = new Segmentation(); 
      segmentation.addListeners(label); //call to addListeners method 

      JFrame frame = new JFrame(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.getContentPane().add(contentPane); 
      frame.setResizable(false); 
      frame.pack(); 
      frame.setLocationByPlatform(true); 
      frame.setVisible(true); 

     } else if(status == JFileChooser.CANCEL_OPTION) { 
      JOptionPane.showMessageDialog(null, "Canceled"); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      TestGraphics tg = new TestGraphics(); 
      tg.newImage(); 
     } 
    }); 
} 

} 

및 기타.

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Line2D; 
import java.util.ArrayList; 
import javax.swing.JLabel; 
import java.awt.event.MouseAdapter; 

public class Segmentation extends JLabel { 

private static final long serialVersionUID = -1481861667880271052L; // unique id 
private static final Color LINES_COLOR = Color.red; 
public static final Color CURRENT_LINE_COLOR = new Color(255, 200, 200); 
ArrayList<Line2D> lineList = new ArrayList<Line2D>(); 
Line2D currentLine = null; 
MyMouseAdapter mouse = new MyMouseAdapter(); 

public void addListeners(Component component) { 
    MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
    component.addMouseListener(myMouseAdapter); 
    component.addMouseMotionListener(myMouseAdapter); 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

    System.out.println("repainting"); 

    g2.setColor(LINES_COLOR); 
    for (Line2D line : lineList) { 
     g2.draw(line); 
    } 
    if (currentLine != null) { 
     g2.setColor(CURRENT_LINE_COLOR); 
     g2.draw(currentLine); 
    } 
} 

private class MyMouseAdapter extends MouseAdapter { 
    Point p1 = null; 

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

    @Override 
    public void mouseReleased(MouseEvent e) { 
     if (currentLine != null) { 
      currentLine = new Line2D.Double(p1, e.getPoint()); 
      lineList.add(currentLine); 
      currentLine = null; 
      p1 = null; 
      System.out.println("about to repaint"); 
      repaint(); 
     } 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     if (p1 != null) { 
      currentLine = new Line2D.Double(p1, e.getPoint()); 
      repaint(); 
     } 
    } 
} 

} 

답변

4

Segmentation 인스턴스를 구성 요소 계층에 절대 추가하지 마십시오. 따라서 paintComponent은 절대 호출되지 않습니다.

당신은 이런 곳 뭔가가 있어야합니다

Segmentation segmentation = new Segmentation(); 
// ... 
component.add(segmentation); // assuming that component is part of a visible component hierarchy 

편집 :

당신은 해당 구성 요소에 마우스 리스너를 등록하지 않습니다. 다음 코드는 꽤 괜찮은 것 같습니다 :

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Line2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.util.ArrayList; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 

public class TestGraphics { 
    private JLayeredPane contentPane; 

    public void newImage() { 
     try { 
      JFileChooser fileChooser = new JFileChooser("."); 
      int status = fileChooser.showOpenDialog(null); 

      if (status == JFileChooser.APPROVE_OPTION) { 
       File selectedFile = fileChooser.getSelectedFile(); 
       System.out.println("The selected file is from the: " + selectedFile.getParent() + " Drive"); 
       System.out.println("Name of file: " + selectedFile.getName()); 
       System.out.println("Opening file"); 

       BufferedImage buffImage = ImageIO.read(new File(selectedFile.getAbsolutePath())); 
       ImageIcon image = new ImageIcon(buffImage); 

       contentPane = new JLayeredPane(); 
       contentPane.setBackground(Color.WHITE); 
       contentPane.setOpaque(true); 
       // getTabbedPane().setComponentAt(tabNum, contentPane); 
       Dimension d = new Dimension(image.getIconWidth(), image.getIconHeight()); 
       Segmentation segmentation = new Segmentation(); 
       segmentation.setIcon(image); 
       segmentation.setSize(d); 
       contentPane.setPreferredSize(d); 
       contentPane.add(segmentation); 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setContentPane(contentPane); 
       frame.setResizable(false); 
       frame.pack(); 
       frame.setLocationByPlatform(true); 
       frame.setVisible(true); 

      } else if (status == JFileChooser.CANCEL_OPTION) { 
       JOptionPane.showMessageDialog(null, "Canceled"); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static class Segmentation extends JLabel { 

     private static final long serialVersionUID = -1481861667880271052L; // unique id 
     private static final Color LINES_COLOR = Color.red; 
     public static final Color CURRENT_LINE_COLOR = new Color(255, 200, 200); 
     ArrayList<Line2D> lineList = new ArrayList<Line2D>(); 
     Line2D currentLine = null; 
     MyMouseAdapter mouse = new MyMouseAdapter(); 

     public Segmentation() { 
      addMouseListener(mouse); 
      addMouseMotionListener(mouse); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

      System.out.println("repainting"); 

      g2.setColor(LINES_COLOR); 
      for (Line2D line : lineList) { 
       g2.draw(line); 
      } 
      if (currentLine != null) { 
       g2.setColor(CURRENT_LINE_COLOR); 
       g2.draw(currentLine); 
      } 
     } 

     private class MyMouseAdapter extends MouseAdapter { 
      Point p1 = null; 

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

      @Override 
      public void mouseReleased(MouseEvent e) { 
       if (currentLine != null) { 
        currentLine = new Line2D.Double(p1, e.getPoint()); 
        lineList.add(currentLine); 
        currentLine = null; 
        p1 = null; 
        System.out.println("about to repaint"); 
        repaint(); 
       } 
      } 

      @Override 
      public void mouseDragged(MouseEvent e) { 
       if (p1 != null) { 
        currentLine = new Line2D.Double(p1, e.getPoint()); 
        repaint(); 
       } 
      } 
     } 

    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       TestGraphics tg = new TestGraphics(); 
       tg.newImage(); 
      } 
     }); 
    } 

} 
+0

감사합니다. 정말 도움이되어서 paintComponent 메소드를 완벽하게 호출했습니다. 그러나 이미지에 그려지는 선은 보이지 않습니다. 왜 이런 일이 일어날 지 아십니까? – Mochi

+1

@ 모치 업데이트 된 답변보기 오른쪽 구성 요소에 마우스 수신기를 등록하지 않았습니다. –

+0

아하 네 말이 맞아. 모든 도움에 감사드립니다. – Mochi

관련 문제