【问题标题】:Trying to add a timer to when mouse movement is detected尝试在检测到鼠标移动时添加计时器
【发布时间】:2017-01-12 13:43:14
【问题描述】:

我正在尝试添加一些代码,这些代码将在鼠标移动一定次数时启动计时器,下面的代码用于鼠标移动。我希望计时器持续 10 秒,并提醒用户计时器已经开始和结束。

public class MouseMotionEvent extends JPanel
    implements MouseMotionListener {
BlankArea blankArea;
JTextArea textArea;
static final String NEWLINE = System.getProperty("line.separator");

public static void main(String[] args) {

    try {

        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();
    } catch (InstantiationException ex) {

        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }

    UIManager.put("swing.boldMetal", Boolean.FALSE);


    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}


private static void createAndShowGUI() {

    JFrame frame = new JFrame("MouseMotionEventDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    JComponent newContentPane = new MouseMotionEvent();
    newContentPane.setOpaque(true); 
    frame.setContentPane(newContentPane);


    frame.pack();
    frame.setVisible(true);
}

public MouseMotionEvent() {
    super(new GridLayout(0,1));
    blankArea = new BlankArea(Color.YELLOW);
    add(blankArea);

    textArea = new JTextArea();
    textArea.setEditable(false);
    JScrollPane scrollPane = new JScrollPane(textArea,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    scrollPane.setPreferredSize(new Dimension(200, 75));

    add(scrollPane);

    blankArea.addMouseMotionListener(this);
    addMouseMotionListener(this);

    setPreferredSize(new Dimension(450, 450));
    setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
}

void eventOutput(String eventDescription, MouseEvent e) {
    textArea.append(eventDescription
            + " (" + e.getX() + "," + e.getY() + ")"
            + " detected on "
            + e.getComponent().getClass().getName()
            + NEWLINE);
    textArea.setCaretPosition(textArea.getDocument().getLength());
}

public void mouseMoved(MouseEvent e) {
    eventOutput("Mouse moved", e);
}

public void mouseDragged(MouseEvent e) {
    eventOutput("Mouse dragged", e);
}

}

【问题讨论】:

  • 小注:JTextAreas 总是使用\n 作为行分隔符,而不是系统的行分隔符。

标签: java eclipse timer


【解决方案1】:

也许我在这里遗漏了一些东西,但你所要求的似乎是一项相当简单的任务。我猜你的问题是设置“定时器”本身? java.util.Timer 类可用于此目的。

所以,对于你的情况,像这样的函数

private void startTimer()
{
    isTimerRunning = true;
    new java.util.Timer().schedule(new java.util.TimerTask()
    {
        @Override
        public void run()
        {
            isTimerRunning = false;
        }
    }, 10000);

}

你必须像这样在 mouseMoved 函数中调用这个函数,

public void mouseMoved(MouseEvent e)
{
    eventOutput("Mouse moved", e);
    if (!isTimerRunning)
    {
        startTimer();
    }
}

您可以将警报代码与设置和重置 isTimerRunning 的代码一起放置。

编辑: 正如 VGR 所提到的,javax.swing.Timer 更适合与其他摆动组件一起使用,尤其是在执行与 GUI 相关的操作时。 从文档中,

一般来说,对于 GUI 相关的任务,我们建议使用 Swing 计时器而不是通用计时器,因为 Swing 计时器都共享相同的、预先存在的计时器线程,并且与 GUI 相关的任务会自动在事件调度线程上执行。但是,如果您不打算从计时器触摸 GUI,或者需要执行冗长的处理,则可以使用通用计时器。

https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

您的代码,修改后使用,javax.swing.Timer,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MouseMotionEvent extends JPanel implements MouseMotionListener
{
BlankArea blankArea;
JTextArea textArea;
private Timer timer;
boolean isTimerRunning = false;
static final String NEWLINE = System.getProperty("line.separator");

public static void main(String[] args)
{
    try
    {

        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    }
    catch (UnsupportedLookAndFeelException ex)
    {
        ex.printStackTrace();
    }
    catch (IllegalAccessException ex)
    {
        ex.printStackTrace();
    }
    catch (InstantiationException ex)
    {

        ex.printStackTrace();
    }
    catch (ClassNotFoundException ex)
    {
        ex.printStackTrace();
    }

    UIManager.put("swing.boldMetal", Boolean.FALSE);

    javax.swing.SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            createAndShowGUI();
        }
    });
}

private static void createAndShowGUI()
{

    JFrame frame = new JFrame("MouseMotionEventDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JComponent newContentPane = new MouseMotionEvent();
    newContentPane.setOpaque(true);
    frame.setContentPane(newContentPane);

    frame.pack();
    frame.setVisible(true);
}

public MouseMotionEvent()
{
    super(new GridLayout(0, 1));
    blankArea = new BlankArea(Color.YELLOW);
    add(blankArea);

    textArea = new JTextArea();
    textArea.setEditable(false);
    JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    scrollPane.setPreferredSize(new Dimension(200, 75));

    add(scrollPane);

    blankArea.addMouseMotionListener(this);
    addMouseMotionListener(this);

    setPreferredSize(new Dimension(450, 450));
    setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

    ActionListener action = new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent event)
        {
            timer.stop();
        }
    };

    timer = new Timer(0, action);
    timer.setInitialDelay(10000);
}

void eventOutput(String eventDescription, MouseEvent e)
{
    textArea.append(eventDescription + " (" + e.getX() + "," + e.getY() + ")" + " detected on " + e.getComponent().getClass().getName() + NEWLINE);
    textArea.setCaretPosition(textArea.getDocument().getLength());
}

public void mouseMoved(MouseEvent e)
{
    eventOutput("Mouse moved", e);
    if (!timer.isRunning())
    {
        timer.start();
    }
}

public void mouseDragged(MouseEvent e)
{
    eventOutput("Mouse dragged", e);
}
}

【讨论】:

  • 在 Swing 应用程序中,javax.swing.Timer 几乎总是比 java.util.Timer 更好的选择。
  • @VGR 实际上取决于用例...如果计时器执行与 GUI 相关的操作,是的 javax.swing.Timer 会更好,但对于后台任务,这真的没关系...我会更新答案以包含信息...谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
相关资源
最近更新 更多