AWT:ScrollPane中的组件:仅重新绘制视口/可见区域

时间:2015-03-01 19:56:44

标签: java awt scrollpane

我有一个自定义Component,其中Canvas扩展为ScrollPane。当我的组件的内部状态发生变化时,我称之为repaint()方法。但是这会导致完全重新绘制(传递给组件的绘制方法的Graphics对象的边界是组件的大小,而不是视口的大小)。这是一个问题,因为组件可能变得非常大(10,000 + px)并且具有复杂的绘制逻辑。

以下代码举例说明了这个问题:

package main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.ScrollPane;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class ScrollPaneTest {
    static class MyCanvas extends Canvas {
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            Rectangle clipBounds = g.getClipBounds();
            System.out.println("paint " + clipBounds.toString());
            g.setColor(Color.black);
            g.drawString(clipBounds.toString(), 20, 20);
        }

//      Attempted solution: doesn't work; MyCanvas.paint() doesn't get called at all.
//      @Override
//      public void repaint(long tm, int x, int y, int width, int height) {
//          System.out.println(tm + " " + x + " " + y + " "
//                  + width + " " + height);
//          getParent().repaint();
//      }

    }

    public static void main(String[] args) throws Exception {
        JFrame frame = new JFrame();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });
        frame.setBounds(0, 0, 400, 200);
        frame.setVisible(true);

        ScrollPane pane = new ScrollPane();
        frame.add(pane);

        MyCanvas mc = new MyCanvas();
        pane.add(mc);
        mc.setBounds(0, 0, 1000, 1000);
        mc.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                System.out.println("keypressed");
                mc.repaint();
            }
        });
        mc.requestFocus();
    }
}

问题:当按下一个键并重新绘制()时,会调用paint(Graphics),打印的clipBounds始终包含整个MyCanvas:

paint java.awt.Rectangle[x=0,y=0,width=1000,height=1000]

而不仅仅是可见区域(400x200)。我搜索过Google / SO但没有发现任何相关内容;有谁知道如何改变这个或找出paint方法中的可见区域?

0 个答案:

没有答案