1

我正在制作一个程序,它有一个可以滚动的图像,如果按下按钮,我不知道如何更新图像(例如:向图像添加绿色椭圆。)它已经绘制了图像进入 JScrollPane 并且您可以滚动,但是当您单击按钮时它不会刷新图像。(代码中的更多详细信息)这是代码:

public class PegMaster extends JPanel implements ActionListener {

    //Note: not complete code
    public PegBox[] pegbox = new PegBox[9];

    public static Dimension size = new Dimension(520, 500);

    public BufferedImage canvas;
    public Graphics2D g2d;
    public JScrollPane scroller;
    JPanel panel;
    private Canvas window;

    JScrollPane pictureScrollPane;

    public PegMaster() {
        JButton button = new JButton("test");
        button.addActionListener(this);
        add(button);

        canvas = new BufferedImage((int)size.getWidth()-30, 75 * GUESSES, BufferedImage.TYPE_INT_RGB);
        g2d = canvas.createGraphics();
        for(int i = 0;i<=pegbox.length-1;i++) {
           pegbox[i] = new PegBox(i, g2d);
        }
        window = new Canvas(new ImageIcon(toImage(canvas)), 1);
        //Class Canvas is a Scrollable JLabel to draw to (the image)
        pictureScrollPane = new JScrollPane(window);
        pictureScrollPane.setPreferredSize(new Dimension((int)size.getWidth()-10, (int)size.getHeight()-20));
        pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
        add(pictureScrollPane);

        //adds the scrollpane, but can't update the image in it
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createGUI();
                //just adds the scrollpane
            }
        });
    }

    public void paint(Graphics g) {
        super.paint(g);

        for(int i = 0;i<=pegbox.length-1;i++) {
            //pegbox[i] = new PegBox(i);
            pegbox[i].draw(g2d);
        }
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }   
        //tried re-making the scrollpane, didn't work.
        //window = new Canvas(new ImageIcon(toImage(canvas)), 1);
        //pictureScrollPane = new JScrollPane(window);
        //pictureScrollPane.setPreferredSize(new Dimension((int)size.getWidth()-10 (int)size.getHeight()-20));
        //pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
        //tried imageupdate: pictureScrollPane.imageUpdate(canvas, 0, 0, 0 (int)size.getWidth()-10, (int)size.getHeight()-20);
        //remove(pictureScrollPane);
        //tried this: pictureScrollPane.revalidate();
        repaint();
    }
}
4

3 回答 3

6

首先,不要使用Canvas它是一个重量级的组件,从长远来看它只会给你带来问题,要么使用JComponent要么JPanel

其次,不要覆盖paintpaintComponent而是使用。 paint做了很多工作,包括绘制边框和子组件之类的东西。如果您使用paintComponent它在绘画层次结构中的正确层上执行您想要做的事情,那就更好了。

第三,永远不要Thread.sleep在事件调度线程中调用类似 while 的东西。这将导致事件队列暂停并停止响应事件,使您的程序看起来像是停止了。

第四,切勿在绘制方法中调用 ( 或任何可能导致重绘请求发生的方法) repaint。您最终只会用尽您的 CPU,并且您将被迫终止该进程。invalidaterevalidate

第五,您没有提供actionPerformed方法,这可能是所有操作(和问题)所在。我想你需要调用window.repaint()并且可能window.invalidate()(以相反的顺序),但由于你没有提供使用此代码,这只是猜测......

于 2012-09-15T00:06:20.953 回答
3

试试这个显示图像的类。这可以添加到JScrollPane

public class ImagePanel extends JPanel {

    public Image img;

    public ImagePanel(Image img){
        this.img = img;
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(img, 0, 0, this);
    }

}

现在将这个类添加到JScrollPane. 要更新它,只需更改图像引用并调用repaint()组件上的方法

于 2012-09-15T01:31:15.540 回答
0

上述解决方案没有解决我的目的,所以我研究并发现了这个。请按照链接查看整个示例。我添加了代码以供参考,以防链接更改。

public class ScrollablePicture extends JLabel
                           implements Scrollable,
                                      MouseMotionListener {

private int maxUnitIncrement = 1;
private boolean missingPicture = false;

public ScrollablePicture(ImageIcon i, int m) {
    super(i);
    if (i == null) {
        missingPicture = true;
        setText("No picture found.");
        setHorizontalAlignment(CENTER);
        setOpaque(true);
        setBackground(Color.white);
    }
    maxUnitIncrement = m;

    //Let the user scroll by dragging to outside the window.
    setAutoscrolls(true); //enable synthetic drag events
    addMouseMotionListener(this); //handle mouse drags
}

//Methods required by the MouseMotionListener interface:
public void mouseMoved(MouseEvent e) { }
public void mouseDragged(MouseEvent e) {
    //The user is dragging us, so scroll!
    Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
    scrollRectToVisible(r);
}

public Dimension getPreferredSize() {
    if (missingPicture) {
        return new Dimension(320, 480);
    } else {
        return super.getPreferredSize();
    }
}

public Dimension getPreferredScrollableViewportSize() {
    return getPreferredSize();
}

public int getScrollableUnitIncrement(Rectangle visibleRect,
                                      int orientation,
                                      int direction) {
    //Get the current position.
    int currentPosition = 0;
    if (orientation == SwingConstants.HORIZONTAL) {
        currentPosition = visibleRect.x;
    } else {
        currentPosition = visibleRect.y;
    }

    //Return the number of pixels between currentPosition
    //and the nearest tick mark in the indicated direction.
    if (direction < 0) {
        int newPosition = currentPosition -
                         (currentPosition / maxUnitIncrement)
                          * maxUnitIncrement;
        return (newPosition == 0) ? maxUnitIncrement : newPosition;
    } else {
        return ((currentPosition / maxUnitIncrement) + 1)
               * maxUnitIncrement
               - currentPosition;
    }
}

public int getScrollableBlockIncrement(Rectangle visibleRect,
                                       int orientation,
                                       int direction) {
    if (orientation == SwingConstants.HORIZONTAL) {
        return visibleRect.width - maxUnitIncrement;
    } else {
        return visibleRect.height - maxUnitIncrement;
    }
}

public boolean getScrollableTracksViewportWidth() {
    return false;
}

public boolean getScrollableTracksViewportHeight() {
    return false;
}

public void setMaxUnitIncrement(int pixels) {
    maxUnitIncrement = pixels;
}
于 2015-08-24T16:04:50.117 回答