还记得鼠标点击的位置吗?数组列表?哈希码?
抱歉,大家,我删除了我的苹果和猫示例:)这是我的问题的更新版本!
我在这里失去了理智。我需要一个能够启发我的人。我已经尝试过几次在这里解释我的问题。希望这一次我的问题会更容易理解。
基本上我有这个框架,并且显示了一个图像。右侧有一个 JList,底部还有另一个 JLabels 面板。这是我的框架的屏幕截图。
当我单击图像时,会弹出一个 JOptionPane,如下所示。然后我输入我的意见。我的 JList 是一个 ArrayList,所以我输入的所有内容都会添加到 JList 和底部的 JPanel 中。
现在,当我将鼠标悬停在我单击的部分上时,您会注意到正方形消失了)。仅当我单击图像以及将标签悬停在底部时,它才会出现。到目前为止,我的标签是 LOLZ NOSE 和 INPUT HERE。
我想要做的是当我将鼠标悬停在标签上时,例如 INPUT HERE,它会显示正方形再次强调我点击的部分。我现在的问题是,当我单击“鼻子”时,它应该在鼻子部分显示一个正方形,并且名称“鼻子”带有黑色背景,但它没有显示。此外,仅显示最后一个标签的方块,而忽略单击的其他标签的位置。
如何获得一个标签来记住我点击的位置?人们说我应该使用 ArrayLists 或 HashCodes 但我不知道如何实现它们。感谢任何可以提供帮助的人。
编辑:顺便说一句,我已经完成了矩形。它仅显示最后输入的标签。以下是一些请求的代码片段!
我如何在 JLabel 上设置文本并更新 JList:
public void updateLabel(){
StringBuilder text = new StringBuilder(); //creates empty builder, capacity 16
for(Object s: tagModel.toArray()) //returns an array containing the elements of the tagModel
text.append(" " + s);
repaint();
hoverLabel.setText(text.toString()); //returns a String
hoverLabel.addMouseMotionListener(this);
hoverPanel.add(hoverLabel);
}
单击时我的 mouseListener:
@Override
public void mouseClicked(MouseEvent event) {
// TODO Auto-generated method stub
x = event.getX();
y = event.getY();
isRectPresent = true;
repaint();
input = JOptionPane.showInputDialog("Enter tag name:");
if((input != null) && !input.isEmpty()){
tagModel.addElement(input);
}
}
悬停时我的 mouseMotionListener:
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
xpos = e.getX(); //gets where the mouse moved
ypos = e.getY();
//checks if the mouse is inside the bounds of the rectangle
if (xpos > x && xpos < x + 100 && ypos > y && ypos < y + 100)
isRectPresent = false;
if(e.getSource() == hoverLabel){
isRectPresent = true;
repaint();
}
repaint();
}
我如何绘画:
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0, 0, null);
if(image != null && isRectPresent){
Stroke stroke = g2.getStroke();
g2.setStroke(new BasicStroke(4));
g2.setColor(Color.WHITE);
g2.drawRect(x-50, y-50, 100, 100);
g2.setStroke(stroke);
}else{
if(xpos > x && xpos < x + 100 && ypos > y && ypos < y + 100){
g.setColor(Color.BLACK);
g.fillRect(x-50, y-50, 100, 25);
g.setColor(Color.WHITE);
g.setFont(new Font("Tahoma", Font.BOLD, 12));
g.drawString(input, x-30, y-30);
}
}
}
如果您希望我添加更多片段,请告诉我! :)
Sorry guys, I deleted my APPLES and CATS example :) Here's the updated version of my question!
I'm losing my sanity here. I need someone who can enlighten me. I've tried a couple of times explaining my problem here. Hopefully, this time, my question will be easier to understand.
Basically I have this frame, and there's an image displayed. There is a JList on the right, and there is another panel for JLabels at the bottom. Here's a screencap of my frame.
When I click on the image, a JOptionPane pops out, like so. And I enter my input. My JList is an ArrayList, so everything I input is added to the JList and the JPanel at the bottom.
Now, when I hover on the the part where I clicked, you noticed that the square disappeared). It only appears when I click the image, and when I hover the label at the bottom. My labels, as of now are LOLZ NOSE and INPUT HERE.
What I want to do is when I hover on the label, for example INPUT HERE, it shows the square again, featuring the part where I clicked. My problem now is when I click on NOSE, which is supposed to be showing a square on the nose part and a the name NOSE with black bg, IT IS NOT SHOWING. Also, only the last label's square is shown, disregarding the other labels' position clicked.
How do I get a label to remember the position of the click I make? People said I should use ArrayLists or HashCodes however I have no idea how to implement them. Thank you to anyone who can help.
Edit: I've already done the rectangle, btw. It's showing only for the last label inputted. Here are some of the code snippets requested!
How I'm setting the text on JLabel and updating the JList:
public void updateLabel(){
StringBuilder text = new StringBuilder(); //creates empty builder, capacity 16
for(Object s: tagModel.toArray()) //returns an array containing the elements of the tagModel
text.append(" " + s);
repaint();
hoverLabel.setText(text.toString()); //returns a String
hoverLabel.addMouseMotionListener(this);
hoverPanel.add(hoverLabel);
}
My mouseListener upon click:
@Override
public void mouseClicked(MouseEvent event) {
// TODO Auto-generated method stub
x = event.getX();
y = event.getY();
isRectPresent = true;
repaint();
input = JOptionPane.showInputDialog("Enter tag name:");
if((input != null) && !input.isEmpty()){
tagModel.addElement(input);
}
}
My mouseMotionListener upon hovering:
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
xpos = e.getX(); //gets where the mouse moved
ypos = e.getY();
//checks if the mouse is inside the bounds of the rectangle
if (xpos > x && xpos < x + 100 && ypos > y && ypos < y + 100)
isRectPresent = false;
if(e.getSource() == hoverLabel){
isRectPresent = true;
repaint();
}
repaint();
}
How I'm painting:
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0, 0, null);
if(image != null && isRectPresent){
Stroke stroke = g2.getStroke();
g2.setStroke(new BasicStroke(4));
g2.setColor(Color.WHITE);
g2.drawRect(x-50, y-50, 100, 100);
g2.setStroke(stroke);
}else{
if(xpos > x && xpos < x + 100 && ypos > y && ypos < y + 100){
g.setColor(Color.BLACK);
g.fillRect(x-50, y-50, 100, 25);
g.setColor(Color.WHITE);
g.setFont(new Font("Tahoma", Font.BOLD, 12));
g.drawString(input, x-30, y-30);
}
}
}
If you want me to add some more snippets, just tell me! :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您应该创建一个 HashMap,如下所示:
Map linkSet = new HashMap();
每当您单击绘图并创建标签时,请使用 put 方法将 JLabel 和图像上的点添加到集合中,其中 JLabel 为键,Point 为值。然后在 JLabel 的 MouseMotionListener 中,使用您的标签作为键,并使用地图的
get(...)
方法从集合中获取相应的点。编辑:
根据 alicedimarco 的评论进行更正。再次感谢!
编辑 2
我想你想再次使用地图。如果您有一个 Map,则可以让它从 JLabel 或 JList 的字符串中检索感兴趣的点,然后将此 Point 传递给正在绘制图像的类,并让它使用该 Point 来绘制矩形。例如,您可以为图像绘制类提供一个名为 displayPoint 的 Point 字段和一个名为 setDisplayPoint(Point p) 的方法。它可以像这样简单:
假设感兴趣的对象位于该点的中心,在paintComponent方法中使用displayPoint:
编辑3:
要获得鼠标单击,非常简单,只需将 MouseListener 添加到保存图像的组件即可:
并在从此鼠标侦听器调用的代码中,使用 JOptionPane 获取用户选择的标签名称,然后添加结果字符串到 listDataModel,以便它可以在 JList 中看到,也可以在 stringPointMap 中与从 MouseEvent 获取的 Point 一起看到,以便您可以将 String 映射到 Point 并能够检索它:
就是这样。
然后把它们放在一起:
You should create a HashMap, say something like:
Map linkSet = new HashMap();
And whenever you click on the drawing and create a label, add the JLabel and the point on the image to the set using the put method with the JLabel as the key and the Point as the value. Then in the JLabel's MouseMotionListener, use your label as a key and obtain the corresponding point from the set using the map's
get(...)
method.edit:
Corrected as per alicedimarco's comment. Again, thanks!
edit 2
I think you want again to use a Map. If you have a Map, you can have it retrieve the Point of interest from the JLabel's or the JList's String, and then pass this Point to the class that's drawing the image and let it use the Point to draw a rectangle. For instance you could give the image drawing class a Point field called displayPoint, and a method called setDisplayPoint(Point p). It can be as simple as this:
and assuming that the object of interest is centered at that point, use the displayPoint in the paintComponent method:
edit 3:
To get mouse clicks, it's quite easy, simply add a MouseListener to the component that holds the image:
And in your code that is called from this mouse listener, use a JOptionPane to get the user's choice of tag name, and add the resulting String to both the listDataModel so that it is seen in the JList and also in the stringPointMap together with the Point obtained from the MouseEvent so that you can map the String to the Point and be able to retrieve it:
That's it.
Then putting it all together:
JList 的一个很好的功能是您可以记录其中的任何对象。您不仅限于字符串。当对象存储在JLists中时,swing将调用对象的toString()方法,并将其显示在列表中。
知道了这一点,您现在可以编写自己的类来存储选择标签的名称和框的坐标。该对象的 toString() 方法将返回标签的名称,这将使正确的内容出现在 JList 中。
然后,在 JList 的选择事件处理程序中,您可以取出自定义对象,检索其中存储的框坐标,并将它们绘制在屏幕上。无需对其他容器大惊小怪(尽管知道如何使用它们是一件好事)。
好的,创建一个这样的类...
上面的类重写了
toString()
,因此当您将其放入 JList 中时,它将使用对toString()
的调用确定要显示的内容,并且由于此 toString 实现返回标签名称,因此您将在列表中看到该名称。并将它们添加到您的 JList 而不是字符串中。然后在你的代码中的某个时刻你会做这样的事情......
希望有帮助。
One nice feature of a JList is that you can story any object in it. You're not limited to strings. When objects are stored in JLists, swing will call the object's toString() method, and display it in the list.
Knowing this, you can now write your own class that stores the name of your selection label and the coordinates of the box. This object's toString() method will return the name of the label, which will make the right thing appear in the JList.
Then, in the selection event handler for the JList, you can get your custom object out, and retrieve the box coordinates stored in it, and draw them on the screen. No need to fuss with other containers (although knowing how to use them is a good thing to).
Ok, Create a class like this...
The class above overrides
toString()
, so when you put it in a JList, it will use the call totoString()
to determine what to display, and since this toString implementation returns the label name you'll see that in the list.And add those into your JList instead of Strings. Then at some point in your code you'll do something like this...
Hope that helps.