问题
I need to change the cursor while it moves over an array-list of rectangles by the contain(p) method.The problem is
- My first algorithm to use an iterator to iterate through the rectangles doesn't work as expected.The cursor only changes when hovering over the first rectangle,in the other rectangles neither does it respond by showing the cursor changing nor indicate through the console that the cursor is hovering above them?!!
- My second solution also refuses to work properly.I use a for loop to iterate over the rectangles, although the rectangles indicate through the console that the mouse is hovering above them, the cursor refuses to change with the exception of the last rectangle.
- I use a JPanel in this SSCCE ,only because it reproduces the problem am encountering using a JTextPane...assuming my coding approach is what is in question.
I am thinking may be I may need to a thread to improve response and performance but not sure about the approach.Thanks in advance people.
public class UnstableCursor extends JPanel{
Rectangle2D rec;
ArrayList<Rectangle2D> recList = new ArrayList<>();
public UnstableCursor(){
}
public static void main(String[] args) {
UnstableCursor uc = new UnstableCursor();
JFrame frame = new JFrame();
Mover mv = new Mover(uc);
uc.addMouseListener(mv);
uc.addMouseMotionListener(mv);
JScrollPane jx = new JScrollPane(uc);
frame.getContentPane().add(jx);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g2d = (Graphics2D)g;
int x = 5;
for(int i = 0;i < 4;i++){
g2d.setColor(Color.red);
rec = new Rectangle2D.Double(20,x,100,5);
g2d.draw(rec);
recList.add(rec);
x += 50;
}
System.out.println("RecList is: " +recList.size());
}
}
class Mover extends MouseInputAdapter{
UnstableCursor uc;
Rectangle2D rec;
ArrayList<Rectangle2D> reList;
public Mover(UnstableCursor ucc){
uc = ucc;
}
@Override
public void mouseDragged(MouseEvent e) {
super.mouseDragged(e);
Point p = e.getPoint();
System.out.println("xxxx");
}
@Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
reList = uc.recList;
//System.out.println("List is: "+reList.size());
Iterator <Rectangle2D> recs = reList.iterator();
//--------------------- First Algorithm ----------------------//
if(recs.hasNext()){
rec = recs.next();
if(rec.contains(p)){
System.out.println("inside the rectangle....");
uc.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
else{
uc.setCursor(Cursor.getDefaultCursor());
}
}
//--------------------- Second Algorithm ---------------------//
int r = 0;
for(int i = 0;i<(reList.size());i++){
rec = reList.get(r);
//System.out.println("Rect No: "+r+"X: "+rec.getX()+"Y: "+rec.getY());
r++;
if(rec.contains(p)){
System.out.println("inside the rectangle....");
uc.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
else{
uc.setCursor(Cursor.getDefaultCursor());
}
}
}
}
回答1:
the cursor refuses to change with the exception of the last rectangle.
Your basic search algorithm is wrong. Once you find a rectangle that contains the point you should set the cursor and break out of the loop, otherwise the next rectangle you check will not be a match and the cursor will be reset again.
Also...
for(int i = 0;i < 4;i++){
g2d.setColor(Color.red);
rec = new Rectangle2D.Double(20,x,100,5);
g2d.draw(rec);
recList.add(rec);
x += 50;
}
... A painting method is for painting only.
You should NOT be creating rectangles and adding them to the array, since the paintComponent() method is continually called when Swing determines the panel needs to be repainted.
The rectangles should be added to the List in the constructor of your class so each rectangle is only added once.
来源:https://stackoverflow.com/questions/46027174/java-swing-mouse-cursor-misbehaves-when-held-over-a-rectangle