有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

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

}


共 (1) 个答案

  1. # 1 楼答案

    那个

    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会发生什么情况的描述)