Trouble with JApplets and calling paint/paintComponent

孤街浪徒 提交于 2019-12-13 06:27:42

问题


So I'm just doing some studying for finals here, and I'm having trouble getting this to work. What I have always done previously is call paintComponent(Graphics g) and things have worked just peachy. But now I'm getting a "paintComponent has protected access in JComponent" error when I go to compile. The only way I could get it to compile was to tell it to call paint. But even if it compiles, paint never gets called in the applet window. What am I not seeing here?

 public class LineDraw extends JComponent
 {
private final Point p1;
private final Point p2;
private final JApplet callingWindow;
private final ArrayList<Line2D.Double> lines;

public LineDraw(JApplet callingWindow)
{
    this.p1 = new Point();
    this.p2 = new Point();
    this.callingWindow = callingWindow;
    this.lines = new ArrayList<Line2D.Double>();
    MouseListener mouse = new MouseHandler();
    callingWindow.addMouseListener(mouse);
}

public class MouseHandler extends MouseAdapter
{
    private boolean firstClick;
    public MouseHandler()
    {
        firstClick = true;
    }
    public void mouseClicked(MouseEvent e)
    {
        if(firstClick)
        {
            p1.setLocation(e.getPoint());
            firstClick = false;
        }
        else    
        {
            p2.setLocation(e.getPoint());
            lines.add(new Line2D.Double(p1, p2));
            p2.setLocation(p1.getLocation());
            callingWindow.repaint();        
        }
    }

    public void paintComponent(Graphics2D g2)
    {
        for(Line2D.Double e: lines)
        {
            g2.draw(e);
        }
    }
}

}

And the applet class itself

    public class AppletWin extends JApplet
    {
private LineDraw lineDrawer;

public void init()
{
    setBackground(Color.white);
    lineDrawer = new LineDraw(this);
}

public void paint(Graphics h)
{
    Graphics2D g = (Graphics2D)h;
    //Clear background
    g.setColor(getBackground());
    g.fillRect(1, 1, getWidth(), getHeight());
    lineDrawer.paintComponent(g);  
}
    }

回答1:


LineDrawer is a component, you should add it to you applet and it will painted automatically.

You seem to have fallen into a naming clash problem.

JComponent defines two methods for painting (actually it defines a few more, but lets keep it simple), paint and paintComponent.

The problem you are having is to do with the fact that you've inherited from a JComponent but seem to be performing your own painting. This fine when you want to develop you own "painter" classes, but falls foul of Swing components. There is more to a Swing component then simply painting it.

The other problem you're have is you've defined a "paint" method in side MouseHandler method and seem to be assuming that it is callable from LineDraw class. The problem is, you're actually calliing the JComponent's paint method, not the one you want/think you are.

Try removing the extends JComponent and moving the paint method into the LineDraw class.

As MouseEvent has stated, under most circumstances, you should never call paint or paintComponent directly.

You may find:

  • Painting in AWT and Swing
  • Performing Custom Painting

Helpful

UPDATED

Painting as a Swing Component

public class AppletWin extends JApplet {

    private LineDraw lineDrawer;

    public void init() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                setBackground(Color.white);
                lineDrawer = new LineDraw(AppletWin.this);
                setLayout(new BorderLayout());
                add(lineDrawer);
            }
        });
    }

    public class LineDraw extends JComponent {

        private final Point p1;
        private final Point p2;
        private final JApplet callingWindow;
        private final ArrayList<Line2D.Double> lines;

        public LineDraw(JApplet callingWindow) {
            this.p1 = new Point();
            this.p2 = new Point();
            this.callingWindow = callingWindow;
            this.lines = new ArrayList<Line2D.Double>();
            MouseListener mouse = new MouseHandler();
            addMouseListener(mouse);
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.RED);
            for (Line2D.Double e : lines) {
                g2.draw(e);
            }
        }

        public class MouseHandler extends MouseAdapter {

            private boolean firstClick;

            public MouseHandler() {
                firstClick = true;
            }

            public void mouseClicked(MouseEvent e) {
                if (firstClick) {
                    p1.setLocation(e.getPoint());
                    firstClick = false;
                } else {
                    p2.setLocation(e.getPoint());
                    lines.add(new Line2D.Double(p1, p2));
                    p2.setLocation(p1.getLocation());
                }
                repaint();
            }
        }
    }
}

As Painter

public class AppletWin extends JApplet {

    private LineDraw lineDrawer;

    public void init() {
        setBackground(Color.white);
        lineDrawer = new LineDraw(this);
    }

    public void paint(Graphics h) {
        // The the applet clear the background
        super.paint(h);
        Graphics2D g = (Graphics2D) h;
        lineDrawer.paintComponent(g);
    }
    public class LineDraw {

        private final Point p1;
        private final Point p2;
        private final JApplet callingWindow;
        private final ArrayList<Line2D.Double> lines;

        public LineDraw(JApplet callingWindow) {
            this.p1 = new Point();
            this.p2 = new Point();
            this.callingWindow = callingWindow;
            this.lines = new ArrayList<Line2D.Double>();
            MouseListener mouse = new MouseHandler();
            callingWindow.addMouseListener(mouse);
        }

        public void paintComponent(Graphics2D g2) {
            System.out.println("...");
            for (Line2D.Double e : lines) {
                g2.draw(e);
            }
        }

        public class MouseHandler extends MouseAdapter {

            private boolean firstClick;

            public MouseHandler() {
                firstClick = true;
            }

            public void mouseClicked(MouseEvent e) {
                if (firstClick) {
                    p1.setLocation(e.getPoint());
                    firstClick = false;
                } else {
                    p2.setLocation(e.getPoint());
                    lines.add(new Line2D.Double(p1, p2));
                    p2.setLocation(p1.getLocation());
                }
                callingWindow.repaint();
            }
        }
    }
}

You really should avoid overriding the paint method of top level containers. The paint method is a very complex method and circumventing it is just going to cause you problems in the long run, besides, it's not double buffered ;)




回答2:


Problem with this code is that the paintComponent method in LineDraw is inside the inner class MouseHandler.



来源:https://stackoverflow.com/questions/13716900/trouble-with-japplets-and-calling-paint-paintcomponent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!