![](/img/trans.png)
[英]use super.paintComponent(g) or getGraphics() in java
[英]Java swing - super.paintcomponent(g) - repaint()
我有兩個類似的類,在MyPanel類中,我重寫了paintComponent
方法,將自己的“圖形”添加到JPanel
。 我之所以調用super.paintComponent(g),是因為據我了解,當我使用自己的繼承方法實現時,我也重寫了此方法的標准“隱藏”功能。 我知道,如果我想在myPanel上使用諸如setBackground / setBorder之類的方法,則必須從擴展類中調用paintComponent方法,以使其以其自己的標准方式(繪畫背景,繪畫寄宿生等)工作。
因此,我認為每當我按下鼠標按鈕時,我都會調用我的moveSquare方法,它將調用repaint方法。 調用repaint方法時,程序將轉到重寫的paintComponent方法。 我知道當我使用
repaint(squareX, squareY, squareW, squareH);
在moveSquare方法中,它將僅重新繪制紅色方塊(不會重新繪制背景),這就是為什么我將在面板上看到每個紅色方塊的原因。 我知道如果我會在第一次調用中使用repaint()然后使用這樣的參數重畫:
repaint();
squareX=x;
squareY=y;
repaint(squareX, squareY, squareW, squareH);
它會重新繪制背景,然后繪制一個正方形,所以我將只能在面板上看到最后一個紅色繪制的正方形。我不明白的是為什么用參數重復調用repaint方法:
repaint(squareX, squareY, squareW, squareH);
squareX=x;
squareY=y;
repaint(squareX, squareY, squareW, squareH);
將首先繪制一個帶有背景顏色的正方形,然后繪制一個紅色(它的行為就像我會在不帶參數的情況下調用重繪,然后在帶參數的情況下重繪)。
很抱歉提供這么長的解釋,但是如果我能解釋我認為它應該如何工作,我會更容易指出我的錯誤。
SwingMoveSquareDemo類
public class SwingMoveSquareDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
System.out.println("GUI started");
createGUI();
}
});
}
public static void createGUI(){
JFrame f = new JFrame("Move square demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
MyPanel類
public class MyPanel extends JPanel {
private int squareX=1;
private int squareY=1;
private int squareW=20;
private int squareH=20;
public MyPanel(){
setBackground(Color.GRAY);
setBorder(BorderFactory.createLineBorder(Color.WHITE));
setPreferredSize(new Dimension(400,250));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
System.out.println("mouspressed");
moveSquare(e.getX(),e.getY());
}
});
}
private void moveSquare (int x, int y){
repaint(squareX, squareY, squareW, squareH);
squareX=x;
squareY=y;
repaint(squareX, squareY, squareW, squareH);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
System.out.println("paint component");
g.setColor(Color.RED);
g.fillRect(squareX, squareY, squareW, squareH);
}
}
這是因為,當您調用repaint()
,它不會立即發生。 它將被放到事件分配線程上,並在以后調用。 同樣,如果您連續調用多個重畫,則可能會重畫其矩形的並集。
因此,當您第一次調用repaint時,它將排隊繪制您指定的矩形。 然后更新正方形的坐標,然后進行繪制,然后將新的矩形與重新繪制排隊,然后將其合並並繪制矩形的並集。執行重新繪制時,它將清除背景該區域,然后繪制正方形。
插入System.out.printf("dirty region = %s%n",g.getClipBounds());
在paintComponent ()
中查看正在繪制的矩形
paintComponent
委托ComponentUI#update
,后者將Graphics
上下文的顏色設置為組件的背景色,並填充0, 0, c.getWidth(), c.getHeight()
(其中c
是對繪制組件的引用)。
基本上,這意味着,即使您使用repaint
或repaint(x, y, width, height)
,背景也會開始完全更新。
區別在於, Graphics
剪輯會更改。 調用repaint
,剪輯將是組件的大小,使用repaint(x, y, width, height)
,剪輯的形狀將與您傳遞的值相同。
您可能需要看一下AWT和Swing中的繪畫以獲取更多詳細信息。
記住,Swing中的繪畫是在RepaintManager
的控制下進行的,它將決定應繪畫什么以及何時繪畫。 當它決定需要進行更新時,它將在事件隊列中放置一個“繪制”事件,該事件將在將來的某個時間由事件調度線程進行處理。 這意味着,在大多數情況下,繪畫不是即時的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.