2016-05-31 18 views
1

我希望藉助JPanel的特定區域,像這樣的(黑色區域是我想要的JPanel重繪):的Java重繪多個區域

enter image description here

下面的代碼是我是如何實現這一點。它跟隨鼠標光標並在鼠標光標點繪製一個圓圈。框架和麪板的尺寸是300 * 300。

public class MiniGraphicTest extends JPanel{ 

private static final long serialVersionUID = 1L; 

public int x,y; 
public MiniGraphicTest() { 
    super(); 
    x = -1; 
    y = -1; 
    addMouseMotionListener(new MouseMotionAdapter(){ 
     @Override 
     public void mouseMoved(MouseEvent m){ 
      x = m.getX()-25; 
      y = m.getY()-25; 
      repaint(100,100,100,100); 
      repaint(200,200,100,100); 
     } 
    }); 
} 
protected void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    ////////////////////// 
    //DO NOT MODIFY HERE// 
    ////////////////////// 
    //Draw gridline 
    int width = this.getWidth(); 
    int height = this.getHeight(); 
    g.setColor(Color.BLACK); 
    for(int i=100;i<width;i+=100){ 
     g.drawLine(i, 0, i, height); 
    } 
    for(int i=100;i<height;i+=100){ 
     g.drawLine(0, i, width, i); 
    } 
    ////////////////////// 
    //put test code here// 
    ////////////////////// 
    if(x == -1&&y==-1) return;//initially draw nothing 
    g.fillOval(x, y, 50, 50); 
} 
}//main function is just showing the panel. nothing special 
public static void main(String[] args) { 
    JFrame jf = new JFrame("Test"); 
    MiniGraphicTest test = new MiniGraphicTest(); 
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    test.setPreferredSize(new Dimension(300, 300)); 
    jf.setResizable(false); 
    jf.add(test); 
    jf.pack(); 
    jf.setVisible(true); 
} 

此代碼的結果是這樣的:

enter image description here

它重繪區域之外進行重新繪製。你能解釋一下爲什麼發生這種情況以及如何解決這個問題?

PS。當鼠標移動中只調用一次重繪(100,100,100,100)時,代碼完全正常工作。

謝謝

+1

看看這個主題可能會對你有所幫助:http://stackoverflow.com/questions/32815493/custom-painting-of-a-swing-component-with-multiple-calls-to-repaint – Berger

+1

只有當鼠標在所需的正方形內。 –

+0

@Berger謝謝你的聯繫。我知道多個repaint()方法將「以某種方式處理」,並且只會重新繪製一次,但它不能解釋爲什麼它會重新繪製不需要的區域,除非假設「process」包含該區域。 – minolee

回答

1

我認爲快速蝸牛的解決方案是一般的正確答案。如果您具有動態大小的板子左右的動態情況,您可以考慮只有當鼠標位於所需的方塊之內時才能繪製圓形。

多次呼叫repaint只會使repaint的較大區域包含您在多次呼叫repaint中指定的所有區域。

但如果你有這個小板與9個細胞,我覺得這是一個快速修復,爲了您的情況不進行後續呼籲repaint

public class MiniGraphicTest extends JPanel { 

    private static final long serialVersionUID = 1L; 

    public int x, y; 
    boolean flag; 

    public MiniGraphicTest() { 
     super(); 
     x = -1; 
     y = -1; 
     addMouseMotionListener(new MouseMotionAdapter() { 
      @Override 
      public void mouseMoved(MouseEvent m) { 
       x = m.getX() - 25; 
       y = m.getY() - 25; 
       if(flag) { 
        repaint(100, 100, 100, 100); 
       } else { 
        repaint(200, 200, 100, 100); 
       } 
       flag = !flag; 
      } 
     }); 
    } 
    // Other codes of yours 
} 

好運。

0

repaint()僅標誌着EDT進行重繪組件。 後續調用不會改變任何內容。

使用座標(矩形)調用repaint只在rect內標記要重新繪製的組件。 後續調用只能更改(擴展)該rect。

如果要將clip繪製到某個區域,則需要在您的paintComponent方法中指定該區域。