簡體   English   中英

Java Swing-super.paintcomponent(g)-repaint()

[英]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是對繪制組件的引用)。

基本上,這意味着,即使您使用repaintrepaint(x, y, width, height) ,背景也會開始完全更新。

區別在於, Graphics剪輯會更改。 調用repaint ,剪輯將是組件的大小,使用repaint(x, y, width, height) ,剪輯的形狀將與您傳遞的值相同。

您可能需要看一下AWT和Swing中的繪畫以獲取更多詳細信息。

記住,Swing中的繪畫是在RepaintManager的控制下進行的,它將決定應繪畫什么以及何時繪畫。 當它決定需要進行更新時,它將在事件隊列中放置一個“繪制”事件,該事件將在將來的某個時間由事件調度線程進行處理。 這意味着,在大多數情況下,繪畫不是即時的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM