关于JAVA按钮事件处理,画简单正余弦曲线

来源:互联网 发布:天下三 男 捏脸数据 编辑:程序博客网 时间:2024/06/05 16:04

这周JAVA作业,要求用按钮实现画图,有关事件处理,第一次接触这种用户组件,不是很了解,
开始的想法是,
在一个线程里,创建一个框架Frame,添加组件在Frame里面,把按钮组件添加到一个画板Panel里,
把画板添加到Frame里,然后对每个按钮添加监听器,然后进行画图。。。结果没用布局管理器,自然是失败了,按钮画板把整个框架覆盖了,,画的内容显示不出来。
采用布局管理器之后,添加按钮的Panel到框架的东边。代码如下:

              JButton sinButton = new JButton("Sin");              JButton cosButton = new JButton("Cos");              JButton lineButton = new JButton("Y-X");              buttonPanel = new JPanel();              buttonPanel.add(sinButton);              buttonPanel.add(cosButton);              buttonPanel.add(lineButton);              sinButton.addActionListener(new DrawSinAction());              cosButton.addActionListener(new DrawCosAction());              lineButton.addActionListener(new DrawLineAction());              this.getContentPane().add(BorderLayout.EAST,buttonPanel);//布局

在然后就是画图了,用内部类,针对每强调内容个按钮设置监听器,由于不太懂,这是第一次画的方法,待会写另一个方法。。

第一个:先想在每个监听器里,为每个曲线都创建一个myComponent用来画图,然后每个都添加到Frame里面,,但是这样会有个问题,第二次画的图与第一个画的图会重叠在一起,无法实现单独显示一个正弦曲线或余弦曲线,折腾了半天,终于找到解决办法,每次画完之后,把之前的组件用remove移除掉,
然后继续画下一个图,,不过这样很麻烦,待会说另一个,代码如下:

           JComponent j1 = new DrawSinComponent();//为每个都写一个继承JComponent的组件           JComponent j2 = new DrawCosComponent();           JComponent j3 = new DrawYxComponent();      private class DrawSinAction implements ActionListener{                   public void actionPerformed(ActionEvent event) {                        add(j1);                     setVisible(true);                     remove(j2);                     j2 = new DrawCosComponent();                     remove(j3);                     j3 = new DrawYxComponent();               }}    private class DrawCosAction implements ActionListener{               public void actionPerformed(ActionEvent event) {                    add(j2);                    remove(j1);                    j1 = new DrawSinComponent();                    remove(j3);                    j3 = new DrawYxComponent();    private class DrawLineAction implements ActionListener{                 public void actionPerformed(ActionEvent event) {                    add(j3);                    setVisible(true);                    remove(j1);                    j1 = new DrawSinComponent();                    remove(j2);                    j2 = new DrawCosComponent();              }}       //比如为Sin曲线写个DrawSinComponent;  public class DrawSinComponent extends JComponent {            @Override        protected void paintComponent(Graphics g) {                    Graphics2D g2 = (Graphics2D) g;                     for(double x=0;x<=360;x+=1)//一个周期             {             double y=Math.sin(x*Math. PI/180);//转化为弧度,1度=π/180弧度             y=(150-80*y);//放大             g2.drawLine((int)x, (int)y, (int)x,(int) y);//画点              }            g2.drawLine(0,150,400,150);//画x轴            g2.drawLine(180,0,180,400);//画y轴            g2.setStroke(new BasicStroke(3.0f));            g2.drawLine(170,10,180,0);//画x箭头            g2.drawLine(180,0,190,10);            g2.drawLine(390,140,400,150);//画y箭头            g2.drawLine(400,150,390,160);      }}

上面这种对每个要画的曲线都写一种Component组件来画图很麻烦,而且每次移除添加组件很频繁,
好像有点奇怪(我是怎么觉得)。。然后就在想怎么在一个Component里面画不同的图,因为有个
repaint的方法可以对之前的重画,就不用反复移除组件,想了一下午之后。。忽然发现可以采用点集,
把每个曲线的点集先存起来,传入就好,然后每次点集更新完就重新画图。只要为要画的曲线创建点集就好啦,,代码如下,基本都差不多,监听器里面修改了下:

DrawXComponent J1=new DrawXComponent();//先在外面建立一个Component,几个曲线共用一个画图组件                                         //只需要改变传入的点集就好了private class DrawSinAction implements ActionListener{                   public void actionPerformed(ActionEvent event) {                         SinPoints s=new SinPoints();//创建一个所需画的曲线的点集                      J1.Draw(s.getPoints());//传入                        add(J1);                        setVisible(true);                 
//将传进来的点集合转化为线集合,画出,然后如果集合发生变化,就用repaint重画,就可以更新之前画的public class DrawXComponent extends JComponent{      private List<Line2D> lines=null;      public DrawXComponent(){              }      public void Draw(List<Point2D> points){                       lines=makeLine(points);//把点转换为线            repaint();      }      @Override              protected void paintComponent(Graphics g) {        Graphics2D g2 = (Graphics2D) g;        g2.drawLine(0,150,400,150);//画x轴        g2.drawLine(180,0,180,400);//画y轴       g2.setStroke(new BasicStroke(3.0f));       g2.drawLine(170,10,180,0);//画x箭头       g2.drawLine(180,0,190,10);       g2.drawLine(390,140,400,150);//画y箭头       g2.drawLine(400,150,390,160);        for(Line2D e:lines){            g2.draw(e);        }        }                         //把给定的点数组转化为线数组的方法      private List<Line2D> makeLine(List<Point2D> points) {            if (points.size()<2) {                throw new IllegalArgumentException("点的数小于2,size="+points.size());            }            List<Line2D> lines = new ArrayList<Line2D>();            for (int i = 0; i < points.size()-1; i++) {                Point2D p1 = points.get(i);                Point2D p2 = points.get(i+1);                lines.add(new Line2D.Double(p1, p2));            }            return lines;           }}

然后就可以实现按一个按钮画一个曲线,效果图贴上来麻烦,大概就这样了。。


才刚开始学,有很多不懂的地方,可能方法复杂了或者做错了,,有不对的地方私信我,,
再学一段时间,有改进的方法下次回来更新。。。

原创粉丝点击