我正在尝试制作一个使用标签来追逐用户鼠标的程序,我有两个问题:
首先,标签的位置由整个计算机屏幕的坐标而不仅仅是窗口来判断。
其次,当计时器使用repaint()
时,标签在应用程序期间不会移动。
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MouseFollowDisplay frame = new MouseFollowDisplay();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MouseFollowDisplay() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JLabel lblNewLabel = new JLabel("RUN!");
lblNewLabel.setRequestFocusEnabled(false);
lblNewLabel.setLocation(new Point(5, 5));
lblNewLabel.setBounds(10, 11, 31, 23);
contentPane.add(lblNewLabel);
contentPane.addMouseListener(new MouseAdapter() {
int DELAY = 500;
ActionListener MouseDetect = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
int x = (int) b.getX();
int y = (int) b.getY();
System.out.println(x + "," + y);
int lx = lblNewLabel.getX();
int ly = lblNewLabel.getY();
if (lx <= x+5 && lx >= x-5 && ly <= y+5 && ly >= y-5){
DetectMouse.stop();
JOptionPane.showMessageDialog(null, "You Lose!");
}else{
lx = -((lx - x) * 5) / (Math.abs(lx - x));
ly = -((ly - y) * 5) / (Math.abs(ly - y));
lblNewLabel.repaint(lx, ly, 31, 23);
}
if (DELAY >= 150) {
DELAY -= 5;
DetectMouse.setDelay(DELAY);
}
}
};
Timer DetectMouse = new Timer(DELAY, MouseDetect);
public void mouseClicked(MouseEvent arg0) {
if (DetectMouse.isRunning()){
DetectMouse.stop();
DELAY = 500;
}
else{
DetectMouse.start();
}
}
});
}
}
答案 0 :(得分:2)
lblNewLabel.repaint(lx, ly, 31, 23)
通话不会移动您的标签。请参阅该重绘方法的javadoc
如果组件正在显示,则将指定的区域添加到脏区列表。在调度了所有当前挂起的事件后,将重新绘制该组件。
您需要做的是调整标签的位置,然后重新绘制面板(标签的旧区域和新区域)。
更好的方法是null
布局拥有您自己的JComponent
或JPanel
,您可以覆盖paintComponent
方法并使用Graphics#drawString
绘制该字符串方法。在这种情况下,请不要忘记致电super.paintComponent
以避免文本多次出现(例如,请参阅this SO question,了解如果您忘记致电super.paintComponent
会发生什么事情)