一个极其痛苦的数组问题,哪为高手能帮小弟解决!急!!!

时间:2022-04-07 15:54:30
这是一个过程线的图,X轴是日期,Y轴是流量,中间显示的是一条折线,我现在已经可以使这条折线左右的移动,但是当折线一旦越过X轴,Y轴的范围,他依然会显示,举个例子吧!我现在向右移的时候进行了判断,使折线在范围外不显示,但是我在向左移的时候,在范围外依然显示,而且我在右移时超出范围的折线数值丢失,我想在左移的时候把它重新显示,可是丢失的折线怎么也显示不出来,还会抛出java.lang.ArrayIndexOutOfBoundsException: -1
的异常。如果哪位仁兄肯帮我的话,就在你的机器上试一下,帮我解决,高分送给。
我用的是JBuilder9

import java.awt.*;

import java.applet.Applet;
import javax.swing.*;
import java.awt.font.*;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.*;
import java.awt.Point;
public  class ProcessLine extends Applet implements KeyListener
{
  int[] xPoints = {
      0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650,
      700};
  int[] yPoints = {
      280, 450, 100, 150, 250, 500, 240, 360, 500, 460, 460, 320, 200,
      450, 230};
  
  public void init() {
    addKeyListener(this);
    setFocusable(true);
   }
  public void poloyLine()
   {
   for(int i=0;i<xPoints.length;i++)
     {
       if(xPoints[i]>=800)
     {
        xPoints[i]=xPoints[i-1];
        yPoints[i]=yPoints[i-1];
     }else
       {
         xPoints[i] += 50;
       }
    }
    repaint();
   }

  public void poloyLine1()
   {  
     for(int i=0;i<xPoints.length;i++)
     {
       xPoints[i] -= 50;
     }
    repaint();
   }
  public void paint(Graphics g)
  {
    g.translate(100,100);
    g.setColor(Color.black);
    g.drawLine(0,0,0,510);
    g.drawLine(0,510,800,510);
    //画背景网格
  g.setColor(Color.lightGray);
     int x =0;
     int y =0;
     int x1=0;
     int y1 =0;

   for (int i = 0; i <16; i++)
   {
    x = 0;
    y += 30;
    x1 = 800;
    y1 += 30;
    g.drawLine(x, y, x1, y1);
    g.drawLine(0,0,800,0);
   }
   int y2 =0;
   int x2 =0;
   int x3 =0;
   int y3 = 510;

    for (int j = 0; j < 16; j++)
   {
     x2 += 50;
     y2 = 0;
     x3 += 50;
     y3 = 510;
     g.drawLine(x2, y2, x3, y3);
   }

  //画折线
  g.setColor(Color.red);
  g.drawPolyline(xPoints, yPoints, xPoints.length);


  //传递节点
  /*int xRect = -45;
  for(int i=0;i<50;i++){

    xRect +=45;
  }
  int yRect = 0;
  for(int i=0;i<50;i++){
   yRect = (int)(Math.random()*495);
  }
  int width = 10;
  int height = 10;
  g.setColor(Color.green);
  g.fill3DRect(xRect,yRect,width,height,true);*/

  //传递流量
   int flux = -5;
   int xString = -20;
   int yString =540;
   for(int i = 0;i<18;i++)
   {
    xString=-20;
    yString -= 30;
    flux += 5;
    String s =String.valueOf(flux);
    g.setColor(Color.black);
    Font f= new Font("宋体",Font.BOLD,14);
    g.setFont(f);
    g.drawString(s,xString,yString);
   }

    //传递日期
    int month = 7;
    xString = -100;
    yString = 520;
  for(int i=0;i<=8;i++)
  {
    month = 7;
    xString += 100;
    yString = 520;
    g.setColor(Color.black);
    Font f= new Font("宋体",Font.BOLD,14);
    g.setFont(f);
    String s1=String.valueOf(month);
    g.drawString(s1,xString,yString);
  }
    int day =1;
    xString = -80;
    yString = 520;
  for(int i=0;i<=8;i++)
  {
    day += 1;
    xString +=100;
    yString = 520;
    g.setColor(Color.black);
    Font f= new Font("宋体",Font.BOLD,14);
    g.setFont(f);
    String s2 = String.valueOf(day);
    g.drawString(s2,xString,yString);
   }
    xString = -90;
    yString = 520;
    for(int i=0;i<=8;i++)
   {
    String s3 = "/";
    xString +=100;
    yString = 520;
    g.setColor(Color.black);
    Font f= new Font("宋体",Font.BOLD,14);
    g.setFont(f);
    g.drawString(s3,xString,yString);
   }
  }
  public void keyPressed(KeyEvent keyEvent) {
    JPanel panel = new JPanel();
     int  keyCode = keyEvent.getKeyCode();
     if(keyCode == KeyEvent.VK_RIGHT){
        poloyLine();
     }
    else if(keyCode == KeyEvent.VK_LEFT){
        poloyLine1();
     }
   }
  public void keyReleased(KeyEvent keyEvent) {
    }
  public void keyTyped(KeyEvent keyEvent) {

    char keyChar = keyEvent.getKeyChar();
    if (keyChar == 'd') {

        poloyLine();
    }
    else if(keyChar == 'a'){
        poloyLine1();
    }
  }
}

10 个解决方案

#1


页是通不过
不过帮你顶一下

#2


看不出有什么毛病。。。这是你所有的代码么?

#3


public void poloyLine()
   {
   for(int i=0;i<xPoints.length;i++)
     {
       if(xPoints[i]>=800)
     {
        xPoints[i]=xPoints[i-1];
        yPoints[i]=yPoints[i-1];
     }else
       {
         xPoints[i] += 50;
       }
    }
    repaint();
   }
你这个算法有点问题。你上面的代码仅仅适合有一个点超出了800这个范围。而且你对y坐标的修改导致了数据不可能恢复。

我的经验说给你,我也没有时间帮助你修改代码,你可以参考一下。
一般做这种曲线的时候,你需要做一个坐标变换,这样就可以保证你的曲线不会超出你的那个绘制区域。至于算法,就是吧你实际表示的数据,转换成屏幕的坐标。一般的方法是这样的。对于x轴,比如说一共是x个点,而你的x轴在屏幕上有y像素,那么对你的实际数据z的屏幕坐标可以这样计算。z*(y/x),当然你还需要考虑你的屏幕区局的原点坐标问题。如果你数学学的可以的话,这些应该不是什么问题,对于y舟也是一样的,这样你就保证,你的图形不会超出那个范围。。

我只能这么帮助你了。

#4


poloyLine1()和poloyLine()有问题

我还没有看完,但是可以解释出了左右边界,回去后就不能显示,
和java.lang.ArrayIndexOutOfBoundsException异常。

1. 你的原数据是xPoints和yPoints,可是在poloyLine1()和poloyLine()方法中改变了这两个数组的内容。
2. 异常是因为poloyLine循环中的判断,但i=0时,i-1就回出错。
3. 左移出Y轴后依然显示是因为poloyLine1中没有进行坐标判断,如果你依然用poloyLine方法中的判断,也会出现ArrayIndexOutOfBoundsException。这次是因为index大于数组长度。

建议:
1 移动显示判断是不要修改原数据。建立两个临时变量,保存要划线的数据。

从这个方向入手,应该可以解决你的问题。
至于ArrayIndexOutOfBoundsException,是数学问题,应该不难了。

#5


谢谢你们的帮助,我基本已经解决了左右移动的功能,现在超出X,Y轴的范围的折线不会在显示,但是在向右移的时候,折线虽然不会在范围外显示,但是折线会落在和Y轴平行的最后一条网格线上,不知道是怎么回事,你们能不能帮我运行一下,看看究竟是怎么回事,代码如下:
package 过程线;

import java.awt.*;
import java.applet.Applet;
import javax.swing.*;
import java.awt.font.*;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.*;
import java.awt.Point;

public class ProcessLine extends Applet implements KeyListener {
  String ParaTime;
  String ParaFlux;
  private boolean isStandalone = false;
  int[] xPoints = {
      0, 20, 30, 70, 190, 240, 300, 350, 400, 450, 500, 550, 600, 650,
      700};
  int[] yPoints = {
      280, 450, 100, 150, 250, 500, 240, 360, 500, 460, 460, 320, 200,
      450, 230};
  int[] xPointstmp = new int[xPoints.length];
  int[] yPointstmp = new int[yPoints.length];
  int[] xPointsshow = new int[xPoints.length];
  int[] yPointsshow = new int[yPoints.length];
  //Get a parameter value
  public String getParameter(String key, String def) {
    return isStandalone ? System.getProperty(key, def) :
        (getParameter(key) != null ? getParameter(key) : def);
  }

  public void init() {
    try {
      ParaTime = this.getParameter("time", "");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    try {
      ParaFlux = this.getParameter("flux", "");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    //xPointstmp=xPoints;
    //yPointstmp=yPoints;
    for (int i = 0; i < xPoints.length; i++) {
      xPointstmp[i] = xPoints[i];
      yPointstmp[i] = yPoints[i];
    }
    xPointsshow = xPoints;
    yPointsshow = yPoints;
    addKeyListener(this);
    setFocusable(true);
  }

  public String[][] getParameterInfo() {
    String[][] pinfo =
      {
      {"time", "String", ""},
      {"flux", "String", ""},
      };
    return pinfo;
  }

  public void paint(Graphics g) {
    g.translate(100, 100);
    g.setColor(Color.black);
    g.drawLine(0, 0, 0, 510);
    g.drawLine(0, 510, 800, 510);
    //画网格
    g.setColor(Color.lightGray);
    int x = 0;
    int y = 0;
    int x1 = 0;
    int y1 = 0;

    for (int i = 0; i < 16; i++) {
      x = 0;
      y += 30;
      x1 = 800;
      y1 += 30;
      g.drawLine(x, y, x1, y1);
      g.drawLine(0, 0, 800, 0);
    }
    int y2 = 0;
    int x2 = 0;
    int x3 = 0;
    int y3 = 510;

    for (int j = 0; j < 16; j++) {
      x2 += 50;
      y2 = 0;
      x3 += 50;
      y3 = 510;
      g.drawLine(x2, y2, x3, y3);
    }

    g.setColor(Color.red);
    g.drawPolyline(xPointsshow, yPointsshow, xPointsshow.length);
    //传递节点
    /*int xRect = -45;
       for(int i=0;i<50;i++){
      xRect +=45;
       }
       int yRect = 0;
       for(int i=0;i<50;i++){
     yRect = (int)(Math.random()*495);
       }
       int width = 10;
       int height = 10;
       g.setColor(Color.green);
       g.fill3DRect(xRect,yRect,width,height,true);*/

    //传递流量
    int flux = -5;
    int xString = -20;
    int yString = 540;
    for (int i = 0; i < 18; i++) {
      xString = -20;
      yString -= 30;
      flux += 5;
      String s = String.valueOf(flux);
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      g.drawString(s, xString, yString);
    }

    //传递日期
    int month = 7;
    xString = -100;
    yString = 520;
    for (int i = 0; i <= 8; i++) {
      month = 7;
      xString += 100;
      yString = 520;
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      String s1 = String.valueOf(month);
      g.drawString(s1, xString, yString);
    }
    int day = 1;
    xString = -80;
    yString = 520;
    for (int i = 0; i <= 8; i++) {
      day += 1;
      xString += 100;
      yString = 520;
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      String s2 = String.valueOf(day);
      g.drawString(s2, xString, yString);
    }
    xString = -90;
    yString = 520;
    for (int i = 0; i <= 8; i++) {
      String s3 = "/";
      xString += 100;
      yString = 520;
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      g.drawString(s3, xString, yString);
    }
  }

  public void keyPressed(KeyEvent keyEvent) {
    JPanel panel = new JPanel();
    int keyCode = keyEvent.getKeyCode();
    if (keyCode == KeyEvent.VK_RIGHT) {
      poloyLineMove(50);//左移
    }
    else if (keyCode == KeyEvent.VK_LEFT) {
      poloyLineMove(-50);//右移
    }
  }

  public void keyReleased(KeyEvent keyEvent) {
  }

  public void keyTyped(KeyEvent keyEvent) {
    char keyChar = keyEvent.getKeyChar();
    if (keyChar == 'd') {
      poloyLineMove(50);
    }
    else if (keyChar == 'a') {
     poloyLineMove(-50);
    }
  }
  public void poloyLineMove(int MoveStep) {
   for (int i = 0; i < xPoints.length; i++) {
     xPointstmp[i] = xPointstmp[i] + MoveStep;
     xPointsshow[i] = xPointstmp[i];
     yPointsshow[i] = yPointstmp[i];
     if (xPointstmp[i] <= 0) {
       xPointsshow[i] = 0;
     }
     else {
       if (i > 0) {
         if (xPointstmp[i - 1] <= 0) {
           for (int k = 0; k < i; k++) {
             yPointsshow[k] = yPointstmp[i - 1];
           }
         }
       }
       if (xPointstmp[i] >= 800) {
         xPointsshow[i] = 800;
       }
       else {
         if (i < xPoints.length - 1) {
           if (xPointstmp[i + 1] >= 800) {
             for (int k = i; k < xPoints.length; k++) {
               yPointsshow[k] = yPointstmp[i + 1];
             }
           }
         }
       }
     }
     //System.out.println(xPointstmp[i]);
   }
   repaint();
 }
}
如果你们运行的话,点击左右光标键就会实现左右移动的功能,就会发现我上面说到的问题,我现在还有几个功能要实现,就是放大和缩小这条折线,你们也应该知道,放大缩小Y坐标是不变的,就是X坐标需要放大或缩小,放大是从我第一次显示的折线开始,缩小是从放大的那条折线开始到第一次显示的折线,他们同样也是可以左右移动的,而且折线在放大,缩小,左右移动的过程中,X轴的时间也是跟着改变的,至于折线每移动多少,时间改变多少,没有严格的要求,那位仁兄如果有时间的话,帮我想想,给点思路,最好能先帮我解决最上面说到的那个问题,再这里小弟先谢谢你们了!

#6


小D没有做过类似的项目,帮你顶一下..和你一起学习!

#7


快来就我呀!我顶不住了!!!!!

#8


收藏一下!

#9


帮你顶一下

#10


顶后再说吧。

#1


页是通不过
不过帮你顶一下

#2


看不出有什么毛病。。。这是你所有的代码么?

#3


public void poloyLine()
   {
   for(int i=0;i<xPoints.length;i++)
     {
       if(xPoints[i]>=800)
     {
        xPoints[i]=xPoints[i-1];
        yPoints[i]=yPoints[i-1];
     }else
       {
         xPoints[i] += 50;
       }
    }
    repaint();
   }
你这个算法有点问题。你上面的代码仅仅适合有一个点超出了800这个范围。而且你对y坐标的修改导致了数据不可能恢复。

我的经验说给你,我也没有时间帮助你修改代码,你可以参考一下。
一般做这种曲线的时候,你需要做一个坐标变换,这样就可以保证你的曲线不会超出你的那个绘制区域。至于算法,就是吧你实际表示的数据,转换成屏幕的坐标。一般的方法是这样的。对于x轴,比如说一共是x个点,而你的x轴在屏幕上有y像素,那么对你的实际数据z的屏幕坐标可以这样计算。z*(y/x),当然你还需要考虑你的屏幕区局的原点坐标问题。如果你数学学的可以的话,这些应该不是什么问题,对于y舟也是一样的,这样你就保证,你的图形不会超出那个范围。。

我只能这么帮助你了。

#4


poloyLine1()和poloyLine()有问题

我还没有看完,但是可以解释出了左右边界,回去后就不能显示,
和java.lang.ArrayIndexOutOfBoundsException异常。

1. 你的原数据是xPoints和yPoints,可是在poloyLine1()和poloyLine()方法中改变了这两个数组的内容。
2. 异常是因为poloyLine循环中的判断,但i=0时,i-1就回出错。
3. 左移出Y轴后依然显示是因为poloyLine1中没有进行坐标判断,如果你依然用poloyLine方法中的判断,也会出现ArrayIndexOutOfBoundsException。这次是因为index大于数组长度。

建议:
1 移动显示判断是不要修改原数据。建立两个临时变量,保存要划线的数据。

从这个方向入手,应该可以解决你的问题。
至于ArrayIndexOutOfBoundsException,是数学问题,应该不难了。

#5


谢谢你们的帮助,我基本已经解决了左右移动的功能,现在超出X,Y轴的范围的折线不会在显示,但是在向右移的时候,折线虽然不会在范围外显示,但是折线会落在和Y轴平行的最后一条网格线上,不知道是怎么回事,你们能不能帮我运行一下,看看究竟是怎么回事,代码如下:
package 过程线;

import java.awt.*;
import java.applet.Applet;
import javax.swing.*;
import java.awt.font.*;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.*;
import java.awt.Point;

public class ProcessLine extends Applet implements KeyListener {
  String ParaTime;
  String ParaFlux;
  private boolean isStandalone = false;
  int[] xPoints = {
      0, 20, 30, 70, 190, 240, 300, 350, 400, 450, 500, 550, 600, 650,
      700};
  int[] yPoints = {
      280, 450, 100, 150, 250, 500, 240, 360, 500, 460, 460, 320, 200,
      450, 230};
  int[] xPointstmp = new int[xPoints.length];
  int[] yPointstmp = new int[yPoints.length];
  int[] xPointsshow = new int[xPoints.length];
  int[] yPointsshow = new int[yPoints.length];
  //Get a parameter value
  public String getParameter(String key, String def) {
    return isStandalone ? System.getProperty(key, def) :
        (getParameter(key) != null ? getParameter(key) : def);
  }

  public void init() {
    try {
      ParaTime = this.getParameter("time", "");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    try {
      ParaFlux = this.getParameter("flux", "");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    //xPointstmp=xPoints;
    //yPointstmp=yPoints;
    for (int i = 0; i < xPoints.length; i++) {
      xPointstmp[i] = xPoints[i];
      yPointstmp[i] = yPoints[i];
    }
    xPointsshow = xPoints;
    yPointsshow = yPoints;
    addKeyListener(this);
    setFocusable(true);
  }

  public String[][] getParameterInfo() {
    String[][] pinfo =
      {
      {"time", "String", ""},
      {"flux", "String", ""},
      };
    return pinfo;
  }

  public void paint(Graphics g) {
    g.translate(100, 100);
    g.setColor(Color.black);
    g.drawLine(0, 0, 0, 510);
    g.drawLine(0, 510, 800, 510);
    //画网格
    g.setColor(Color.lightGray);
    int x = 0;
    int y = 0;
    int x1 = 0;
    int y1 = 0;

    for (int i = 0; i < 16; i++) {
      x = 0;
      y += 30;
      x1 = 800;
      y1 += 30;
      g.drawLine(x, y, x1, y1);
      g.drawLine(0, 0, 800, 0);
    }
    int y2 = 0;
    int x2 = 0;
    int x3 = 0;
    int y3 = 510;

    for (int j = 0; j < 16; j++) {
      x2 += 50;
      y2 = 0;
      x3 += 50;
      y3 = 510;
      g.drawLine(x2, y2, x3, y3);
    }

    g.setColor(Color.red);
    g.drawPolyline(xPointsshow, yPointsshow, xPointsshow.length);
    //传递节点
    /*int xRect = -45;
       for(int i=0;i<50;i++){
      xRect +=45;
       }
       int yRect = 0;
       for(int i=0;i<50;i++){
     yRect = (int)(Math.random()*495);
       }
       int width = 10;
       int height = 10;
       g.setColor(Color.green);
       g.fill3DRect(xRect,yRect,width,height,true);*/

    //传递流量
    int flux = -5;
    int xString = -20;
    int yString = 540;
    for (int i = 0; i < 18; i++) {
      xString = -20;
      yString -= 30;
      flux += 5;
      String s = String.valueOf(flux);
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      g.drawString(s, xString, yString);
    }

    //传递日期
    int month = 7;
    xString = -100;
    yString = 520;
    for (int i = 0; i <= 8; i++) {
      month = 7;
      xString += 100;
      yString = 520;
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      String s1 = String.valueOf(month);
      g.drawString(s1, xString, yString);
    }
    int day = 1;
    xString = -80;
    yString = 520;
    for (int i = 0; i <= 8; i++) {
      day += 1;
      xString += 100;
      yString = 520;
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      String s2 = String.valueOf(day);
      g.drawString(s2, xString, yString);
    }
    xString = -90;
    yString = 520;
    for (int i = 0; i <= 8; i++) {
      String s3 = "/";
      xString += 100;
      yString = 520;
      g.setColor(Color.black);
      Font f = new Font("宋体", Font.BOLD, 14);
      g.setFont(f);
      g.drawString(s3, xString, yString);
    }
  }

  public void keyPressed(KeyEvent keyEvent) {
    JPanel panel = new JPanel();
    int keyCode = keyEvent.getKeyCode();
    if (keyCode == KeyEvent.VK_RIGHT) {
      poloyLineMove(50);//左移
    }
    else if (keyCode == KeyEvent.VK_LEFT) {
      poloyLineMove(-50);//右移
    }
  }

  public void keyReleased(KeyEvent keyEvent) {
  }

  public void keyTyped(KeyEvent keyEvent) {
    char keyChar = keyEvent.getKeyChar();
    if (keyChar == 'd') {
      poloyLineMove(50);
    }
    else if (keyChar == 'a') {
     poloyLineMove(-50);
    }
  }
  public void poloyLineMove(int MoveStep) {
   for (int i = 0; i < xPoints.length; i++) {
     xPointstmp[i] = xPointstmp[i] + MoveStep;
     xPointsshow[i] = xPointstmp[i];
     yPointsshow[i] = yPointstmp[i];
     if (xPointstmp[i] <= 0) {
       xPointsshow[i] = 0;
     }
     else {
       if (i > 0) {
         if (xPointstmp[i - 1] <= 0) {
           for (int k = 0; k < i; k++) {
             yPointsshow[k] = yPointstmp[i - 1];
           }
         }
       }
       if (xPointstmp[i] >= 800) {
         xPointsshow[i] = 800;
       }
       else {
         if (i < xPoints.length - 1) {
           if (xPointstmp[i + 1] >= 800) {
             for (int k = i; k < xPoints.length; k++) {
               yPointsshow[k] = yPointstmp[i + 1];
             }
           }
         }
       }
     }
     //System.out.println(xPointstmp[i]);
   }
   repaint();
 }
}
如果你们运行的话,点击左右光标键就会实现左右移动的功能,就会发现我上面说到的问题,我现在还有几个功能要实现,就是放大和缩小这条折线,你们也应该知道,放大缩小Y坐标是不变的,就是X坐标需要放大或缩小,放大是从我第一次显示的折线开始,缩小是从放大的那条折线开始到第一次显示的折线,他们同样也是可以左右移动的,而且折线在放大,缩小,左右移动的过程中,X轴的时间也是跟着改变的,至于折线每移动多少,时间改变多少,没有严格的要求,那位仁兄如果有时间的话,帮我想想,给点思路,最好能先帮我解决最上面说到的那个问题,再这里小弟先谢谢你们了!

#6


小D没有做过类似的项目,帮你顶一下..和你一起学习!

#7


快来就我呀!我顶不住了!!!!!

#8


收藏一下!

#9


帮你顶一下

#10


顶后再说吧。