2015-10-18 62 views
0

我有一個包含已添加到其中的自定義組件的面板。除了組件(有自己的鼠標偵聽器)被拖動時,它會正確繪製,開始繪製怪異。父面板不能正確重新繪製

有趣的是,如果我稍微重新大小的父面板現在它將塗料作爲預期。我知道父面板正在通過

super.paintComponent(g); 

和打印語句粉刷面板

paintComponent(Graphics g): 

方法內。當組件被拖動時(因爲組件被重新設置),我嘗試重新驗證它會失效。仍然我沒有成功,並想知道是否有人可以提供幫助。

有沒有一些地方我沒有正確重新粉刷,可能會導致這種行爲?

另外作爲一個附錄,我在面板和它的組件上都有一個鼠標監聽器,有沒有辦法讓單擊組件時,面板鼠標監聽器也會響應(除了回到父類組件)

這裏是我有

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.Line2D; 
import javax.swing.*; 

public class testHome { 

    private JFrame frame; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        testHome window = new testHome(); 
        window.frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the application. 
    */ 
    public testHome() { 
     initialize(); 
    } 

    /** 
    * Initialize the contents of the frame. 
    */ 
    private void initialize() { 
     frame = new JFrame(); 
     frame.setBounds(100, 100, 450, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel panel = new myPanel(); 
     frame.getContentPane().add(panel, BorderLayout.CENTER); 
    } 
} 

class myPanel extends JPanel { 

    MyComponent comp; 

    public myPanel() { 
     super(null); 
     comp = new MyComponent(5, 5); 
     this.add(comp); 
     revalidate(); 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     Line2D.Double line = new Line2D.Double(10, 10, comp.getX(), comp.getY()); 
     System.out.println(comp.getX() + " " + comp.getY()); 
     g2d.draw(line); 
    } 
} 

class MyComponent extends JComponent implements MouseListener, MouseMotionListener { 

    int x; 
    int y; 

    int mx; 
    int my; 

    public MyComponent(int x, int y) { 
     this.setVisible(true); 
     this.setBounds(x, y, 15, 15); 
     this.x = x; 
     this.y = y; 
     addMouseMotionListener(this); 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.black); 
     g2d.fillRect(this.x, this.y, 15, 15); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     // TODO Auto-generated method stub 
     System.out.println("dragging"); 
     int dx = e.getX() - mx; 
     int dy = e.getY() - my; 
     this.setBounds(this.getX() + dx, this.getY() + dy, 15, 15); 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     mx = e.getX(); 
     my = e.getY(); 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) {} 

    @Override 
    public void mouseClicked(MouseEvent e) {} 

    @Override 
    public void mouseEntered(MouseEvent e) {} 

    @Override 
    public void mouseExited(MouseEvent e) {} 

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

爲了更快得到更好的幫助,請發佈[MCVE]或[簡短,獨立,正確的示例](http://www.sscce.org/)。 –

+0

順便說一句 - 如果在上面的文字中有一個問題,你可以在它的末尾添加一個「?」嗎? –

+0

完成並完成@AndrewThompson – user3466639

回答

2

父面板實際上並沒有得到完全自動重繪問題的工作示例。 paintComponent()被調用,但如果通過檢查的剪裁,例如:

System.out.println(g.getClipBounds()); 

,你會看到只有小部分下方的區域被繪製。 (組件不是不透明的,所以父組件需要繪製它下面的區域)。您需要顯式調用repaint()父面板:

getParent().repaint(); 

(或使用該repaint()的變種,指定區域,如果父組件是藉助價格昂貴,可以優化局部平)。