我在 Jpanel 上 点击 鼠标 时,会产生一个点,并且用一个小圆圈表示。
 
  部分代码如下:
                  Point point = evt.getPoint();
Graphics g = this.MainPanel.getGraphics();
Graphics2D g2d = (Graphics2D)g ;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

g2d.setColor(Color.black);

Ellipse2D cirl = new Ellipse2D.Double(point.x-2, point.y-2,point.x+2,point.y+2);
cirl.setFrameFromDiagonal(point.x-2, point.y-2,point.x+2,point.y+2);

g2d.draw((Shape)cirl);
this.CountTextField.setText(""+count);
        
shape.add(cirl); // shape是一个ArrayList. ArrayList<Shape> shape = new ArrayList<Shape>();
                 //把cirl添加到shape中
g.dispose();
 
 在点击了这些点后,我又在panel上 画了条直线 部分代码如下:
Graphics g = this.MainPanel.getGraphics();
Graphics2D g2d = (Graphics2D)g ;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GREEN);
Shape line=new Line2D.Double(x, 0.0, 0.0,y);
g2d.draw(line);
g.dispose();现在panel上有一些点和一条直线。然后我在panel上,定义了一个Jbutton按钮,我想要实现点击这个按钮,删除那条直线但是保留那些点。我的思路是:先 rpaint(); 在利用ArrayList<Shape> shape = new ArrayList<Shape>() 中保存的shape 重画那些圆点。我在Jbutton的点击事件里面,写了如下代码: private void EraseActionPerformed(ActionEvent evt) {
 
                  this.MainPanel.repaint();      
                  Graphics g = this.MainPanel.getGraphics();
Graphics2D g2d = (Graphics2D)g ;
g2d.setColor(Color.red);

for(int i=0;i<shape.size();i++)
{
g2d.draw((Shape)shape.get(i));
}

}
 
结果问题出现了:
            
           每当我点击这个Jbutton按钮时,整个panel画板都会被清空,而 g2d.draw((Shape)shape.get(i)) 这个地方
  
   想画的圆点却在panel上显示不出来。    这是为什么啊?   大家帮忙看看。

解决方案 »

  1.   

    楼主一开始,就走弯路了。其实JPanel 不是用来画画的 Canvas 才是用来画画的。
      

  2.   

    最后还要加repaint()吧楼主这样写有点怪。
    可以这样:把直线也加到shape里面。点击按钮时把直线从shape里去掉。每次都是画shape里的所有Shape对象,然后repaint().
      

  3.   


    如果把直线加到 shape里面,就会出现这种情况:直线和圆圈在ArrayList里面的存取就没规律了。
    我如果只删除直线的shape,很难做到,因为你要确定它们在ArrayList里面的index位置。是这样的:我可能点几个点,画条直线,再点几个点,在画条直线。
      

  4.   


    Java code    private void EraseActionPerformed(ActionEvent evt) {
             
                      this.MainPanel.repaint();                 
                      Graphics g = this.MainPanel.getGraphics();            
            Graphics2D g2d = (Graphics2D)g ;    
            g2d.setColor(Color.red);
            
            for(int i=0;i<shape.size();i++)
            {
                g2d.draw((Shape)shape.get(i));
            }    
        }
    你把这里面的:this.MainPanel.repaint();  去掉,就画出来了
      

  5.   

    private void EraseActionPerformed(ActionEvent evt) {
             
                      this.MainPanel.repaint();                 
                      Graphics g = this.MainPanel.getGraphics();         //不建议使用该方法   
            Graphics2D g2d = (Graphics2D)g ;    
            g2d.setColor(Color.red);
            
            for(int i=0;i<shape.size();i++)
            {
                g2d.draw((Shape)shape.get(i));
            }
            
        }上面这种通过使用getGraphics()得到Graphics对象,然后,在这个Graphics对象上进行绘制,看起来好像可以,实际上是万万不行的。因为这个Graphics对象是个瞬间对象,在特定某一段时间是有效的,其它时间是无效的,即使利用它绘制了不少东西,而且JVM没有抱怨,但是,这不代表是正确的。有效时间段是在paintComponent(Graphics g){ },---这里我们只说Swing包下的JComponent。所以在其它地方,其它时间,是无效的,这一定要注意,不然,写出的代码,看上去,逻辑没有问题,但看到现象,另人难过。所以,一般的做法是重载JPanel的paintComponent(Graphics g)方法,利用这个g来绘制List<Shape>中的东西,如果需要更新List<Shape>中的内容时,只需在JButton的动作监听器中:actionPerformed(ActionEvent e){},实现list.add,或是list.remove等方法,也就可以了,当然,在actionPerformed方法中,最后,一句肯定是repaint()方法。
      

  6.   

    我想是你忘了写 repaint
    用JPanel可以重写paintComponent方法
      

  7.   

    我写了一个 可以运行 技术有限你满看。import javax.swing.*;
    import java.awt.geom.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    public class Ellipse2DLine2D 
    {
    public static void main(String[] args) 
    {
    TestFrame frame = new TestFrame();
    frame.setVisible(true);
    }
    }class TestFrame extends JFrame{
    TestFrame(){
    setBounds(200,200,500,400);
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    add(new TestPanel());
    }
    }class TestPanel extends JPanel{
    private ArrayList<Ellipse2D> list;
    private static final double SIDE = 10.0;
    private Ellipse2D ell;
    private Line2D l; TestPanel(){
    l = null;
    ell = null;
    list = new ArrayList<Ellipse2D>(); JButton line = new JButton("Line");
    JButton ellipse = new JButton("Ellipse");
    JButton clear = new JButton("clear"); //add Buttons
    add(ellipse);
    add(line);
    add(clear); //addActionListener
    ellipse.addActionListener(new addEllipse());
    line.addActionListener(new addLine());
    clear.addActionListener(new clearButton());

    } //draw all
    public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    for(Ellipse2D e : list){
    g2.draw(e);
    }
    if(l!=null)
    g2.draw(l);

    }
    //innerClass with Panel
    private class addEllipse implements ActionListener{
    public void actionPerformed(ActionEvent e){
    double d = 50*Math.random();
    ell = new Ellipse2D.Double(100.0+d,100.0+d,SIDE,SIDE);
    list.add(ell);
    repaint();
    }
    }
    //innerClass with Panel
    private class addLine implements ActionListener{
    public void actionPerformed(ActionEvent e){
    l = new Line2D.Double(200,200,400,200);
    repaint();
    }
    }
    //innerClass with Panel
    private class clearButton implements ActionListener{
    public void actionPerformed(ActionEvent e){
    l = null;
    repaint();
    }
    }
    }
      

  8.   


    谢谢你了。上面的问题都解决了。在问你一个问题。我想在以下两点之间画条直线(-84,0),(0,1)我试了下:g2d.draw(new Line2D.Double(-84,0,0,1)) ;
     
       和 g2d.drawLine(-84, 0, 0, 1) ; 两种方式画,但是都画不出来,为什么啊?我把点换成其他的点,有时就可以画出来。