JScrollPane里我定义了ColumnHeaderView和RowHeaderView,当我绘制的图形超出当前的JScrollPane大小时,会自动出现ScrollBar,但当我移动ScrollBar时,却发现我在ColumnHeaderView和RowHeaderView里做的标尺Ruler没有被刷新。该怎样做呢?部分代码如下:(以下代码其实是Java Sample里的)望高手指点。 public ScrollDemo2() { 
area = new Dimension(0,0); 
circles = new Vector(); 
drawingPane = new DrawingPane(); 
scroller = new JScrollPane(drawingPane); 
scroller.setPreferredSize(new Dimension(20,20)); 
columnView = new Rule(Rule.HORIZONTAL, true); 
rowView = new Rule(Rule.VERTICAL, true); 
scroller.setColumnHeaderView(columnView); 
scroller.setRowHeaderView(rowView); 
} public class DrawingPane extends JPanel { 
protected void paintComponent(Graphics g) { 
super.paintComponent(g); 
Rectangle rect; 
for (int i = 0; i < circles.size(); i++) { 
rect = (Rectangle)circles.elementAt(i); 
g.setColor(colors[(i % color_n)]); 
g.fillOval(rect.x, rect.y, rect.width, rect.height); 
} Dimension d = scroller.getPreferredSize(); 
columnView.setPreferredWidth((int) d.getWidth()); 
rowView.setPreferredHeight((int) d.getHeight()); 
columnView.paintComponents(g); 
rowView.paintComponents(g); 

} public void mouseReleased(MouseEvent e) { 
final int W = 100; 
final int H = 100; 
boolean changed = false; 
if (SwingUtilities.isRightMouseButton(e)) { 
} else { 
int x = e.getX() - W/2; 
int y = e.getY() - H/2; 
if (x < 0) x = 0; 
if (y < 0) y = 0; 
Rectangle rect = new Rectangle(x, y, W, H); 
circles.addElement(rect); 
drawingPane.scrollRectToVisible(rect); 
int this_width = (x + W + 2); 
if (this_width > area.width) { 
area.width = this_width; changed=true; 

int this_height = (y + H + 2); 
if (this_height > area.height) { 
area.height = this_height; changed=true; 


if (changed) { 
drawingPane.setPreferredSize(area); 
drawingPane.revalidate(); 
columnView.setPreferredWidth((int)area.getWidth()); 
rowView.setPreferredHeight((int)area.getHeight()); 
scroller.setColumnHeaderView(columnView); 
scroller.setRowHeaderView(rowView); 
scroller.revalidate(); 

drawingPane.repaint(); 
scroller.repaint(); 
}

解决方案 »

  1.   

    附上全部代码,共3个文件分3次传送.这样高手可以运行一下程序,指点一下
    首先是ScrollDemo2.java:import javax.swing.*;
    import javax.swing.event.MouseInputAdapter;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    public class ScrollDemo2 extends JPanel implements MouseListener {
        private Dimension area; //indicates area taken up by graphics
        private Vector circles; //coordinates used to draw graphics
        private JPanel drawingPane;
        private final Color colors[] = {
            Color.red, Color.blue, Color.green, Color.orange,
            Color.cyan, Color.magenta, Color.darkGray, Color.yellow};
        private final int color_n = colors.length;    
        private Rule columnView;
        private Rule rowView;
        private JToggleButton isMetric;
        private JPanel buttonCorner;
        private JScrollPane scroller;    public ScrollDemo2() {
            super(new BorderLayout());
            area = new Dimension(0,0);
            circles = new Vector();
            JLabel instructionsLeft = new JLabel("Click left mouse button to place a circle.");
            JLabel instructionsRight = new JLabel("Click right mouse button to clear drawing area.");
            JPanel instructionPanel = new JPanel(new GridLayout(0,1));
            instructionPanel.add(instructionsLeft);
            instructionPanel.add(instructionsRight);
            drawingPane = new DrawingPane();
            drawingPane.setBackground(Color.white);
            drawingPane.addMouseListener(this);
            scroller = new JScrollPane(drawingPane);
            scroller.setPreferredSize(new Dimension(20,20));
            add(instructionPanel, BorderLayout.PAGE_START);
            add(scroller, BorderLayout.CENTER);
            columnView = new Rule(Rule.HORIZONTAL, true);
            rowView = new Rule(Rule.VERTICAL, true);
            buttonCorner = new JPanel(); //use FlowLayout
            isMetric = new JToggleButton("cm", true);
            isMetric.setMargin(new Insets(1, 1, 1, 1));
            isMetric.setPreferredSize(new Dimension(27, 27));
            buttonCorner.add(isMetric);        
            scroller.setViewportBorder(BorderFactory.createLineBorder(Color.BLACK));
            scroller.setColumnHeaderView(columnView);
            scroller.setRowHeaderView(rowView); 
            scroller.setCorner(JScrollPane.UPPER_LEADING_CORNER, buttonCorner);
            scroller.setCorner(JScrollPane.LOWER_LEADING_CORNER, new Corner());
            scroller.setCorner(JScrollPane.UPPER_TRAILING_CORNER, new Corner());
        }    public class DrawingPane extends JPanel {
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Rectangle rect;
                for (int i = 0; i < circles.size(); i++) {
                    rect = (Rectangle)circles.elementAt(i);
                    g.setColor(colors[(i % color_n)]);
                    g.fillOval(rect.x, rect.y, rect.width, rect.height);
                }
                
                Dimension d = scroller.getPreferredSize();
             columnView.setPreferredWidth((int) d.getWidth());
                rowView.setPreferredHeight((int) d.getHeight());
                System.out.println(d);
                columnView.paintComponents(g);
                rowView.paintComponents(g);
            }
        }    public void mouseReleased(MouseEvent e) {
            final int W = 100;
            final int H = 100;
            boolean changed = false;
            if (SwingUtilities.isRightMouseButton(e)) {
                circles.removeAllElements();
                area.width=0;
                area.height=0;
                changed = true;
            } else {
                int x = e.getX() - W/2;
                int y = e.getY() - H/2;
                if (x < 0) x = 0;
                if (y < 0) y = 0;
                Rectangle rect = new Rectangle(x, y, W, H);
                circles.addElement(rect);
                drawingPane.scrollRectToVisible(rect);
                int this_width = (x + W + 2);
                if (this_width > area.width) {
                    area.width = this_width; changed=true;
                }
                int this_height = (y + H + 2);
                if (this_height > area.height) {
                    area.height = this_height; changed=true;
                }
            }
            if (changed) {
                drawingPane.setPreferredSize(area);
                drawingPane.revalidate();
                columnView.setPreferredWidth((int)area.getWidth());
                rowView.setPreferredHeight((int)area.getHeight());
                scroller.setColumnHeaderView(columnView);
                scroller.setRowHeaderView(rowView);
                scroller.revalidate();
            }
            drawingPane.repaint();
            scroller.repaint();
        }
        public void mouseClicked(MouseEvent e){}
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}
        public void mousePressed(MouseEvent e){}    private static void createAndShowGUI() {
            JFrame.setDefaultLookAndFeelDecorated(true);
            JFrame frame = new JFrame("ScrollDemo2");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JComponent newContentPane = new ScrollDemo2();
            newContentPane.setOpaque(true); //content panes must be opaque
            frame.setContentPane(newContentPane);
            frame.pack();
            frame.setVisible(true);
        }    public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }
      

  2.   

    接下来是Rule.javaimport java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    import java.awt.Toolkit;
    import javax.swing.JComponent;public class Rule extends JComponent {
    public static final int INCH = Toolkit.getDefaultToolkit().getScreenResolution();
    public static final int HORIZONTAL = 0;
    public static final int VERTICAL = 1;
    public static final int SIZE = 35;
    public int orientation;
    public boolean isMetric;
    private int increment;
    private int units;
    public boolean isMetric() { return this.isMetric; }
    public void setIsMetric(boolean isMetric) {
    this.isMetric = isMetric;
    setIncrementAndUnits();
    repaint();
    } public int getIncrement() { return increment; } public void setPreferredHeight(int ph) { 
    setPreferredSize(new Dimension(SIZE, ph));
    } public void setPreferredWidth(int pw) { 
    setPreferredSize(new Dimension(pw, SIZE));
    } public Rule(int o, boolean m) {
    orientation = o;
    isMetric = m;
    setIncrementAndUnits();
    } private void setIncrementAndUnits() {
    if(isMetric) {
    units = (int)((double)INCH / (double)2.54); // dots per centimeter
    increment = units;
    } else {
    units = INCH;
    increment = units / 2;
    }
    } protected void paintComponent(Graphics g) {
    Rectangle drawHere = g.getClipBounds();
    g.setColor(Color.ORANGE);
    g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
    g.setFont(new Font("SansSerif", Font.PLAIN, 10));
    g.setColor(Color.BLACK);
    int end = 0;
    int start = 0;
    int tickLength = 0;
    String text = null;
    if(orientation == HORIZONTAL) {
    start = (drawHere.x / increment) * increment;
    end = (((drawHere.x + drawHere.width) / increment) + 1) * increment;
    } else {
    start = (drawHere.y / increment) * increment;
    end = (((drawHere.y + drawHere.height) / increment) + 1) * increment;
    }
    if(start == 0) {
    text = Integer.toString(0) + (isMetric ? " cm" : " in");
    tickLength = 10;
    if(orientation == HORIZONTAL) {
    g.drawLine(0, SIZE - 1, 0, SIZE - tickLength - 1);
    g.drawString(text, 2, 21);
    } else {
    g.drawLine(SIZE - 1, 0, SIZE - tickLength - 1, 0);
    g.drawString(text, 9, 10);
    }
    text = null;
    start = increment;
    }
                    for(int i = start; i < end; i += increment) {
    if(i % units == 0)  {
    tickLength = 10;
    text = Integer.toString(i / units);
    } else {
    tickLength = 7;
    text = null;
    } if(tickLength != 0) {
    if(orientation == HORIZONTAL) {
    g.drawLine(i, SIZE - 1, i, SIZE - tickLength - 1);
    if(text != null) {
    g.drawString(text, i - 3, 21);
    }
    } else {
    g.drawLine(SIZE - 1, i, SIZE - tickLength - 1, i);
    if(text != null) {
    g.drawString(text, 9, i + 3);
    }
    }
    }
    }
    }
    }
      

  3.   

    最后是Corner.java:
    import java.awt.Color;
    import java.awt.Graphics;import javax.swing.JComponent;public class Corner extends JComponent {
    protected void paintComponent(Graphics g) {
    g.setColor(Color.ORANGE);
    g.fillRect(0, 0, getWidth(), getHeight());
    }
    }