JScrollPane + Canvas: проблема рендеринга - PullRequest
1 голос
/ 28 марта 2012

Я работаю над Java-версией MS Paint.Вы можете видеть, как это выглядит до сих пор здесь .(изображения слишком высокие и их много, чтобы их можно было вставить в вопрос)

Используется JScrollPane для перемещения подкласса Canvas.Если вы не измените размер окна, оно будет работать нормально.Если вы сделаете окно меньше , на первый взгляд оно будет работать точно так же.

Однако, если вы прокрутите вокруг , станет очевидно, что приложениерендеринг того же «окна просмотра», только что переехал.Если вы продолжаете прокручивать , становится более очевидным, что он перекрывает все остальное.

Таким образом, по сути, он отображает неправильный видовой экран.Изменение размера окна обновляет окно просмотра, чтобы быть правильным.Если вы попытаетесь нарисовать на серой области, она будет хорошо нарисована, вы просто не сможете ее увидеть.

Я пытался сделать repaint() на холсте при каждом перемещении полос прокрутки.Это ничего не изменило.

Что мне сделать, чтобы это исправить?

Это код для фрейма: (аргумент img - это изображение, на котором он будет рисовать. У вас естьsetVisible(true) и себе)

import java.awt.*;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;


public class JPaint extends JFrame {
    JPaintPanel panel;
    public JPaint(BufferedImage img) {
        super("Edit your image");
        panel = new JPaintPanel(img);
        setContentPane(panel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Trial and error got me these numbers.
        //I have no idea how find the proper size...
        setSize(img.getWidth()+20-1, img.getHeight()+50+50+2);
    }
    //go to the panel you hold, ask it to retrieve it from the canvas
    public BufferedImage grabImage() {
        return panel.grabImage();
    }
}


class JPaintPanel extends JPanel {
    JTools toolbar;
    JCanvas canvas;
    JScrollPane scrollPane;
    public JPaintPanel(BufferedImage img) {
        super(new BorderLayout());
        toolbar = new JTools();
        canvas = new JCanvas(img);
        JScrollPane scrollPane = new JScrollPane(canvas);
        scrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                canvas.repaint();
            }

        });
        scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                canvas.repaint();
            }

        });
        setPreferredSize(new Dimension(img.getWidth(),img.getHeight()+50));
        add(toolbar, BorderLayout.PAGE_START);
        add(scrollPane, BorderLayout.CENTER);
    }
    public BufferedImage grabImage() {
        return canvas.getImage();
    }
}
class JTools extends JPanel {
    JSlider scale;

    public JTools() {
        scale= new JSlider(JSlider.HORIZONTAL,
                                    0, 400, 100);
        scale.setMajorTickSpacing(100);
        scale.setPaintTicks(true);
        scale.setPaintLabels(true);
        scale.setPreferredSize(new Dimension(300,50));
        add(scale);
    }

}
class JCanvas extends Canvas {

    BufferedImage im;
    Graphics2D g2d;
    Point old = new Point();
    Point now = new Point();

    public JCanvas(BufferedImage imIn) {
        im = imIn;
        g2d = im.createGraphics();


        setPreferredSize(new Dimension(im.getWidth(), im.getHeight()));


        setColor(Color.WHITE);
        setWidth(4);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        //g2d.drawRect(5, 5, 40, 20);

        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                //System.out.println(e.getPoint());
                //g2d.fillRect(e.getX()-5, e.getY()-5, 10, 10);
                old=e.getPoint();
                now=e.getPoint();
                g2d.drawLine(e.getX(), e.getY(), e.getX(), e.getY());
                repaint();
            }
        });
        addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent e) {
                //System.out.println(e.getPoint());
                old=e.getPoint();
                now=e.getPoint();
                g2d.drawLine(e.getX(), e.getY(), e.getX(), e.getY());
                repaint();
            }
        });
        addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e) {
                //System.out.println(e.getPoint());
                //g2d.fillRect(e.getX()-5, e.getY()-5, 10, 10);
                old=now;
                now=e.getPoint();
                g2d.drawLine((int)old.getX(), (int)old.getY(), (int)now.getX(), (int)now.getY());
                repaint();
            }
        });
    }
    public void paint(Graphics g) {
        //super.paint(g);
        update(g);
    }
    public void update(Graphics g) {
        //super.update(g);
        g.drawImage(im, 0, 0, null);
        getToolkit().sync();
    }
    public void setWidth(float w) {
        g2d.setStroke(new BasicStroke(w, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    }
    public void setColor(Color c) {
        g2d.setColor(c);
    }
    public BufferedImage getImage() {
        return im;
    }
}

1 Ответ

1 голос
/ 28 марта 2012
class JCanvas extends Canvas { 

Не смешивайте Swing с компонентами AWT без уважительной причины.Расширьте JComponent вместо этого.

...