0

我正在尝试制作一个使用标签来追逐用户鼠标的程序,我有两个问题:

首先,标签的位置是通过整个计算机屏幕的坐标来判断的,而不仅仅是窗口。

其次,当计时器使用时,标签在应用期间不会移动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();    
            }
        }   
    });
}

}

4

1 回答 1

2

lblNewLabel.repaint(lx, ly, 31, 23)

通话不会移动您的标签。请参阅该重绘方法的 javadoc

如果组件正在显示,则将指定区域添加到脏区域列表。在所有当前挂起的事件都被调度后,组件将被重新绘制。

您要做的是调整标签的位置,然后重新绘制面板(标签的旧区域和新区域)。

比布局更好的方法null是拥有自己的布局JComponentJPanel在其中覆盖paintComponent方法并使用该方法绘制该字符串Graphics#drawString。在这种情况下,不要忘记调用super.paintComponent以避免文本多次出现(例如,请参阅this SO question,了解如果您忘记调用会发生什么super.paintComponent

于 2012-05-08T21:14:25.587 回答