java - 使用计时器更新 jframe 组件的位置

标签 java swing jframe mouseevent jlabel

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

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

其次,当计时器使用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();    
            }
        }   
    });
}

}

最佳答案

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

调用不会移动你的标签。请参阅该重绘方法的 javadoc

Adds the specified region to the dirty region list if the component is showing. The component will be repainted after all of the currently pending events have been dispatched.

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

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

关于java - 使用计时器更新 jframe 组件的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10505404/

相关文章:

java - 比较 DTO 与 Java 中的域模型是否相等

java - Hibernate 中的带注释的类

java - 在 Android 上解压缩大文件

java - Pdfbox pdf查看器代码

java - 从 VLC 命令行获取正在播放信息

java - 设置 JFileChooser 的最小/最大大小 - Java

java - 这些花括号有什么作用?

java - JFrame getRootPane() 返回 Null

java - 模态 JDialog 的最佳位置以避免卡住

java - 在整个JFrame上添加 "global"列表器以检查字段更改