gpt4 book ai didi

java - Java 中时间序列数据中用户选择的标记

转载 作者:行者123 更新时间:2023-12-01 15:46:01 24 4
gpt4 key购买 nike

我的代码在默认宽度为 581 像素的面板中绘制 5000 点时间序列数据,但当用户调整窗口大小时,此宽度会发生变化。我的代码还绘制了几个矩形标记,每个标记都标识同一空间中的局部最大值/峰值。

我需要使用户能够右键单击任何矩形峰值标记,以便用户可以手动删除任何虚假峰值。问题是,当用户右键单击峰值标记时,我的代码报告的 x 坐标与预期不同。我怀疑原因可能与从 581 x 像素转换回 5000 个数据索引时的舍入误差有关。但我不确定原因。

任何人都可以建议一种解决方案,使我的用户能够通过右键单击上述峰值标记之一来手动选择它吗?

我附上了下面代码的相关部分。我的实际代码非常非常长,而且太复杂,无法发布。但下面的相关部分应该足以让人们了解我的方法的逻辑,然后提出更有效的方法。

声明相关类的代码是:

class SineDraw extends JPanel implements MouseMotionListener, MouseListener {
// lots of code, including the two segments excerpted below
}

这段代码重载了 JPanel 的paintComponent,以便绘制我的数据:

// declare some variables
ArrayList<Double> PeakList = new ArrayList<Double>() // this ArrayList is populated by an extraneous process
visiblePoints = 5000
hstep = getWidth()/visiblePoints //=581/5000 by default, but will change when user resizes window
int numPeaks = PeakList.size();

// scale (y-coordinate) data relative to height of panel
pts = new double[visiblePoints]
for (int i = 0; i < pts.length-1; i++){pts[i]=//data vertical scaled to fill panel;}

// plot the 5000 time-series-data-points within the 581 pixels in x-axis
for (int i = 1; i < visiblePoints; i++) {
int x1 = (int) ((i - 1) * hstep);
int x2 = (int) (i * hstep);
int y1 = (int)pts[i - 1];
int y2 = (int)pts[i];
g2.drawLine(x1, y1, x2, y2);
}

// plot a rectangle for each of the local peaks
for(int m=0;m<=(numPeaks-1);m++){
if(i==(int)(PeakList.get(m)){
int currentVal = (int)pts[(int)(PeakList.get(m)];
g2.drawRect((int)(PeakList.get(m), currentVal, 6, 6);
}
}

这部分代码用于处理鼠标右键:

public void mousePressed(MouseEvent e){
// check to see if right mouse button was clicked
boolean jones = (e.getModifiers()&InputEvent.BUTTON3_MASK)==InputEvent.BUTTON3_MASK;
if(jones==true){
// test the value returned as x-coordinate when user right-clicks (code always underestimates x-coordinate of local peaks by this test)
double ReverseHstep = visiblePoints/getWidth();
int getX_ConvertedTo_i = (int) (e.getX()*ReverseHstep);
System.out.println("getX_ConvertedTo_i is: "+getX_ConvertedTo_i );

// check to see if peaklist contains a value within the x-coordinates of the user-selected-rectangle
if(PeakList.contains((double)(e.getX()-3))
||PeakList.contains((double)(e.getX()-2))
||PeakList.contains((double)(e.getX()-1))
||PeakList.contains((double)(e.getX()))
||PeakList.contains((double)(e.getX()+1))
||PeakList.contains((double)(e.getX()+2))
||PeakList.contains((double)(e.getX()+3))
){
// handling code will go here, but for now it is a print test that never succeeds because x-coordinate is always underestimated
System.out.println("You just selected a peak!");
}
}
repaint();
}

最佳答案

我建议您为每个您想要可点击的内容创建对象(在本例中为矩形)。这是一个过于简单的示例,说明如何使您绘制的内容可点击。需要注意的关键是 mouseClicked 方法,只有当鼠标在矩形内单击时,该方法才会显示一个对话框。

一个棘手的问题是,我无法弄清楚如何使矩形填充颜色而不在其上绘制另一个矩形。我会把那个留给你;-)

public class Canvas extends JPanel implements MouseListener{
private Rectangle rect = new Rectangle(100,100);

public Canvas(){
this.addMouseListener(this);
rect.setSize(100, 100);
}

@Override
public void paintComponent(Graphics g){
g.setClip(rect);
g.setColor(Color.RED);
g.fillRect(0, 0, 100, 100);
}

@Override
public void mouseClicked(MouseEvent e){
if(rect.contains(e.getPoint())){
JOptionPane.showConfirmDialog(this, "Click!");
}
}

// The rest of the MouseListener methods have been cut out

public static void main(String[] a){
JFrame frame = new JFrame("Canvas Thingy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 300, 300);
frame.add(new Canvas());
frame.setVisible(true);
}
}

关于java - Java 中时间序列数据中用户选择的标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6988692/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com