Используя Java Swing, mouseEntered затмевается mouseMoved. Есть ли это легко исправить?
По сути, мне нужно просто нарисовать текст "Mouse Mouse at", а затем его координаты. Мой код делает это успешно, когда mouseMoved не реализован. Когда это так, он никогда не показывает, что мышь вошла, и сразу переходит к "Мышь перемещена в". Я могу понять, как mouseMoved может сделать это, поскольку вход в панель также перемещает мышь в этом месте. Я пытался сохранить ходы в векторе и отобразить их (пока не обязательно для этого проекта), но он все равно не закрасил то, что вводила мышь. Это заставляет меня подозревать, что есть нечто более глубокое, вызывающее это. Есть ли легкое исправление?
Я извиняюсь за необработанный, незавершенный код (незаконченный в том смысле, что он еще не делает все, что мне нужно, но он компилируется и запускается со своим аналогом GUI).
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
public class DrawingArea extends JPanel {
int x1, x2, y1, y2;
int shapeType;
char mouseAction;
Vector<String> eventList = new Vector<String>();
public DrawingArea() {
initialize();
}
public void initialize() {
addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent m) {
x1 = m.getX();
y1 = m.getY();
mouseAction = 'a';
shapeType = 0;
repaint();
}
public void mouseExited (MouseEvent m) {
x1 = m.getX();
y1 = m.getY();
mouseAction = 'b';
shapeType = 0;
repaint();
}
public void mousePressed(MouseEvent m) {
x1 = m.getX();
y1 = m.getY();
mouseAction = 'd';
shapeType = 0;
repaint();
}
public void mouseReleased(MouseEvent m) {
x2 = m.getX();
y2 = m.getY();
repaint();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved (MouseEvent m) {
x2 = m.getX();
y2 = m.getY();
mouseAction = 'c';
shapeType = 0;
repaint();
}
public void mouseDragged(MouseEvent m) {
x2 = m.getX();
y2 = m.getY();
repaint();
}
});
}
public void output(String event, MouseEvent m) {
}
public void setShapeType(int num) {
if (num == 1) {
shapeType = 1;
mouseAction = 'z';
repaint();
}
else if (num == 2) {
shapeType = 2;
mouseAction = 'z';
repaint();
}
else if (num == 3) {
shapeType = 0;
mouseAction = 'z';
repaint();
}
}
public void paint(Graphics g) {
super.paint(g);
if (shapeType == 1) {
g.drawString("Rectangle", 25,25);
}
else if (shapeType == 2)
g.drawString("Circle", 25, 25);
if (mouseAction == 'a') {
g.drawString("Mouse entered at (" + x1+ ", " + y1 + ")", 25, 25);
}
else if (mouseAction == 'b') {
g.drawString("Mouse exited at (" + x1 + ", " + y1 + ")", 25, 25);
}
else if (mouseAction == 'c') {
g.drawString("Mouse moved at (" + x2 + ", " + y2 + ")", 25, 25);
}
else if (mouseAction == 'd')
g.drawString("Mouse clicked at (" + x1 + ", " + y1 + ")", 25, 25);
}
}
Для справки вот код GUI:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleGUI extends JFrame {
DrawingArea drawArea = new DrawingArea();
public SimpleGUI() {
createGUI();
}
public void createGUI() {
JFrame main = new JFrame();
main.setVisible(true);
main.setSize(500, 600);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel right = new JPanel(new GridLayout(20,1));
JPanel bottom = new JPanel();
JButton rect = new JButton("Rectangle");
JButton circ = new JButton("Circle");
JButton erase = new JButton("Erase");
JButton send = new JButton("Send");
JTextField text = new JTextField(30);
right.add(rect);
right.add(circ);
right.add(erase);
bottom.add(text);
bottom.add(send);
drawArea.setBackground(Color.WHITE);
main.add(drawArea, BorderLayout.CENTER);
main.add(right, BorderLayout.EAST);
main.add(bottom, BorderLayout.SOUTH);
rect.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
drawArea.setShapeType(1);
}
});
circ.addActionListener (new ActionListener(){
public void actionPerformed(ActionEvent e) {
drawArea.setShapeType(2);
}
});
erase.addActionListener (new ActionListener() {
public void actionPerformed(ActionEvent e) {
drawArea.setShapeType(3);
}
});
}
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SimpleGUI();
}
});
}
}
1 ответ
Проблема не в слушателях, а в логике рендеринга...
if (mouseAction == 'a') {
g.drawString("Mouse entered at (" + x1 + ", " + y1 + ")", 25, 25);
} else if (mouseAction == 'b') {
g.drawString("Mouse exited at (" + x1 + ", " + y1 + ")", 25, 25);
} else if (mouseAction == 'c') {
g.drawString("Mouse moved at (" + x2 + ", " + y2 + ")", 25, 25);
} else if (mouseAction == 'd') {
g.drawString("Mouse clicked at (" + x1 + ", " + y1 + ")", 25, 25);
}
В основном, когда мышь входит, она вызывает mouseAction
из a
который сразу же сопровождается mouseAction
из c
,
Я бы предположил, что менеджер по перерисовке никогда не получает время для a
так как c
переопределяет это.
Если вы обновили свой код рисования, чтобы разделить логику между движением и действием, вы сможете увидеть разницу.
g.drawString("Mouse " + (mouseEntered ? "entered" : "exited") + " at (" + x1 + ", " + y1 + ")", 25, 50);
if (mouseAction == 'c') {
g.drawString("Mouse moved at (" + x2 + ", " + y2 + ")", 25, 25);
} else if (mouseAction == 'd') {
g.drawString("Mouse clicked at (" + x1 + ", " + y1 + ")", 25, 25);
}
Я добавил mouseEntered
поле, которое является простым boolean
значение, установленное на true
от mouseEntered
а также false
от mouseExited
Кроме того, конвенция предпочитает отменять paintComponent
метод скорее paint
, paintComponent
с двойной буферизацией, paint
нет.