0

ラベルを使用してユーザーのマウスを追跡するプログラムを作成しようとしていますが、2つの問題があります。

まず、ラベルの位置は、ウィンドウだけでなく、コンピュータ画面全体の座標によって判断されます。

第二に、タイマーがを使用する場合、ラベルはアプリケーション中に移動しません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)

call はラベルを移動しません。その repaint メソッドの javadoc を参照してください

コンポーネントが表示されている場合、指定されたリージョンをダーティ リージョン リストに追加します。コンポーネントは、現在保留中のすべてのイベントがディスパッチされた後に再描画されます。

あなたがしなければならないことは、ラベルの位置を調整し、パネルを再描画することです (ラベルの古い領域と新しい領域の両方)。

より良いアプローチは、nullレイアウトに独自のものを用意するJComponentか、メソッドJPanelをオーバーライドしてpaintComponentメソッドを使用してその文字列をペイントすることGraphics#drawStringです。この場合、super.paintComponentテキストが複数回表示されないように呼び出すことを忘れないでください (たとえば、呼び出すのを忘れた場合に何が起こるかについては、この SO の質問super.paintComponentを参照してください) 。

于 2012-05-08T21:14:25.587 に答える