麻烦JApplets并调用paint / paintComponent

时间:2012-12-05 05:31:47

标签: java repaint japplet jcomponent

所以我只是在这里做一些学习决赛,但是我无法让它发挥作用。我之前一直在做的是调用paintComponent(Graphics g) 事情只是很好的。但是现在我在编译时得到了“paintComponent在JComponent中具有受保护的访问”错误。我可以让它编译的唯一方法是告诉它调用paint。但即使它编译,也不会在applet窗口中调用paint。我在这里看不到什么?

 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);
        }
    }
}

}

小程序类本身

    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);  
}
    }

2 个答案:

答案 0 :(得分:1)

LineDrawer是一个组件,你应该将它添加到applet中,它会自动绘制。

您似乎陷入了命名冲突问题。

JComponent定义了两种绘画方法(实际上它定义了一些,但让我们保持简单),paintpaintComponent

你遇到的问题是你从JComponent继承但似乎在表演自己的画作。当你想要开发自己的“画家”课程时,这很好,但与Swing组件相悖。还有更多的Swing组件,然后只是绘制它。

你遇到的另一个问题是你在MouseHandler方法中定义了一个“paint”方法,似乎假设它可以从LineDraw类调用。问题是,你实际上正在调用JComponent的{​​{1}}方法,而不是你想要/认为你的方法。

尝试删除paint并将extends JComponent方法移至paint类。

正如MouseEvent所说,在大多数情况下,您不应该直接致电LineDrawpaint

你可能会发现:

有用的

<强>已更新

绘画作为摇摆组件

paintComponent

作为画家

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();
            }
        }
    }
}

你真的应该避免覆盖顶级容器的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(); } } } } 方法。 paint方法是一种非常复杂的方法,从长远来看,绕过它只会给你带来问题,而且它不是双缓冲的;)

答案 1 :(得分:0)

此代码的问题在于LineDraw中的paintComponent方法位于内部类MouseHandler中。