等待光标并禁用Java应用程序 [英] Wait cursor and disable java application

查看:53
本文介绍了等待光标并禁用Java应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望用户按下按钮以启动后台线程.

正在处理线程时,我希望发生两件事:

1)应该显示一个WAIT_CURSOR.

2)应用程序不应响应鼠标事件.

按照 setCursor文档当此组件的contains方法针对当前光标位置返回true且此组件可见,可显示且启用时,将显示此光标图像.

我希望在处理此后台线程时禁用我的应用程序.

任何想法如何获得我想要的功能?

  import java.awt.Component;导入java.awt.Cursor;导入java.awt.event.ActionEvent;导入java.awt.event.ActionListener;导入javax.swing.JButton;导入javax.swing.JFrame;导入javax.swing.JOptionPane;导入javax.swing.JPanel;导入javax.swing.SwingUtilities;公共类WaitCursor扩展JFrame{私有静态最终长serialVersionUID = 1L;公共WaitCursor(){setResizable(false);setName(getClass().getSimpleName());setTitle(我的框架");setSize(300,300);getContentPane().add(new MyButtonPanel());}私有类MyButtonPanel扩展了JPanel{私有静态最终长serialVersionUID = 1L;公共MyButtonPanel(){JButton btnStart =新的JButton("Start");btnStart.addActionListener(new BtnStartActionListener());添加(btnStart);}私有类BtnStartActionListener实现ActionListener{公共无效actionPerformed(ActionEvent e){//更改为WAIT_CURSOR组件根= SwingUtilities.getRoot((JButton)e.getSource());JOptionPane.showMessageDialog(root,等待10秒");root.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));;//TODO:禁用根组件会阻止显示WAIT_CURSORroot.setEnabled(false);new Thread(新的TimeKiller(root)).start();}}}私有类TimeKiller实现Runnable{组件_root;公共TimeKiller(组件根){_root =根;}公共无效run(){尝试{Thread.sleep(10 * 1000);}捕获(InterruptedException e){//忽略它}//改回默认光标JOptionPane.showMessageDialog(_root,完成等待");_root.setCursor(Cursor.getDefaultCursor());_root.setEnabled(true);}}私有静态无效createAndShowGUI(){//创建并设置窗口.WaitCursor框架=新的WaitCursor();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}公共静态void main(String [] args){SwingUtilities.invokeLater(new Runnable(){公共无效run(){尝试{createAndShowGUI();}捕获(异常e){e.printStackTrace();System.exit(0);}}});}} 

解决方案

禁用它的一种方法是使用玻璃窗格来阻止鼠标输入.

例如:

  import java.awt.Cursor;导入java.awt.Dimension;导入java.awt.event.ActionEvent;导入java.awt.event.MouseAdapter;导入javax.swing.*;@SuppressWarnings(序列")公共类WaitCursor2扩展了JPanel {私有静态最终int PREF_W = 400;私有静态最终int PREF_H = PREF_W;私有JComponent glassPane;私有JButton runBackgroundProcBtn;private JTextArea textarea =新的JTextArea(15,30);公共WaitCursor2(JComponent glassPane){this.glassPane = glassPane;glassPane.setFocusable(true);glassPane.addMouseListener(new MouseAdapter(){});//因此它将捕获鼠标事件.添加(新的JTextField(10));add(runBackgroundProcBtn = new JButton(new AbstractAction(运行后台进程"){@Override公共无效actionPerformed(ActionEvent arg0){runBackgroundProcessAction();}}));添加(新的JScrollPane(textarea));}私人无效runBackgroundProcessAction(){disableSystem(true);glassPane.setVisible(true);新的SwingWorker< Void,Void>(){@Override受保护的Void doInBackground()引发异常{长时间睡眠时间= 5000;Thread.sleep(sleepTime);返回null;}@Override受保护的void done(){disableSystem(false);}}.执行();}public void disableSystem(boolean disable){glassPane.setVisible(disable);runBackgroundProcBtn.setEnabled(!disable);如果(禁用){System.out.println("started");glassPane.requestFocusInWindow();//因此无法将文本添加到文本组件glassPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));} 别的 {System.out.println("done");glassPane.setCursor(Cursor.getDefaultCursor());}}@Override公共维度getPreferredSize(){返回新的Dimension(PREF_W,PREF_H);}私人静态void createAndShowGui(){JFrame框架=新的JFrame("WaitCursor2");WaitCursor2 mainPanel =新的WaitCursor2((JComponent)frame.getGlassPane());frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.getContentPane().add(mainPanel);frame.pack();frame.setLocationByPlatform(true);frame.setVisible(true);}公共静态void main(String [] args){SwingUtilities.invokeLater(new Runnable(){公共无效run(){createAndShowGui();}});}} 

如果玻璃窗格设置为可见并指定了MouseListener,它将捕获鼠标事件.如果将其设置为不可见,它将失去他的能力.同样,如果将焦点插入并赋予焦点,它将插入符从文本组件中拉出.

I want to have the user press a button to kick off a background thread.

While the thread is processing, I want two things to happen:

1) A WAIT_CURSOR should be displayed.

2) The application should not respond to mouse events.

As per the setCursor documentation "This cursor image is displayed when the contains method for this component returns true for the current cursor location, and this Component is visible, displayable, and enabled. ".

I want my application to be disabled while this background thread is processing.

Any ideas how to get the functionality I want?

import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class WaitCursor extends JFrame
{
    private static final long    serialVersionUID    = 1L;

    public WaitCursor()
    {
        setResizable(false);

        setName(getClass().getSimpleName());
        setTitle("My Frame");
        setSize(300, 300);

        getContentPane().add(new MyButtonPanel());

    }

    private class MyButtonPanel extends JPanel
    {

        private static final long    serialVersionUID    = 1L;

        public MyButtonPanel()
        {
            JButton btnStart = new JButton("Start");
            btnStart.addActionListener(new BtnStartActionListener());
            add(btnStart);
        }

        private class BtnStartActionListener implements ActionListener
        {
            public void actionPerformed(ActionEvent e)
            {
                // Change to WAIT_CURSOR
                Component root = SwingUtilities.getRoot((JButton) e.getSource());
                JOptionPane.showMessageDialog(root, "Wait 10 seconds");
                root.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

                // TODO: Disabling the root component prevents the WAIT_CURSOR from being displayed
                root.setEnabled(false);
                new Thread(new TimeKiller(root)).start();
            }
        }
    }

    private class TimeKiller implements Runnable
    {
        Component    _root;

        public TimeKiller(Component root)
        {
            _root = root;
        }

        public void run()
        {
            try
            {
                Thread.sleep(10 * 1000);
            }
            catch (InterruptedException e)
            {
                // Ignore it
            }
            // Change back to DEFAULT CURSOR
            JOptionPane.showMessageDialog(_root, "Done waiting");
            _root.setCursor(Cursor.getDefaultCursor());
            _root.setEnabled(true);
        }
    }

    private static void createAndShowGUI()
    {
        // Create and set up the window.
        WaitCursor frame = new WaitCursor();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    createAndShowGUI();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    System.exit(0);
                }
            }
        });
    }

}

解决方案

One way to disable it is to use the glass pane to block mouse input.

For example:

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;

import javax.swing.*;

@SuppressWarnings("serial")
public class WaitCursor2 extends JPanel {

   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private JComponent glassPane;
   private JButton runBackgroundProcBtn;
   private JTextArea textarea = new JTextArea(15, 30);

   public WaitCursor2(JComponent glassPane) {
      this.glassPane = glassPane;
      glassPane.setFocusable(true);
      glassPane.addMouseListener(new MouseAdapter() {
      }); // so it will trap mouse events.

      add(new JTextField(10));
      add(runBackgroundProcBtn = new JButton(new AbstractAction(
            "Run Background Process") {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            runBackgroundProcessAction();
         }
      }));
      add(new JScrollPane(textarea));
   }

   private void runBackgroundProcessAction() {
      disableSystem(true);
      glassPane.setVisible(true);
      new SwingWorker<Void, Void>() {
         @Override
         protected Void doInBackground() throws Exception {
            long sleepTime = 5000;
            Thread.sleep(sleepTime);
            return null;
         }

         @Override
         protected void done() {
            disableSystem(false);
         }
      }.execute();
   }

   public void disableSystem(boolean disable) {
      glassPane.setVisible(disable);
      runBackgroundProcBtn.setEnabled(!disable);
      if (disable) {
         System.out.println("started");
         glassPane.requestFocusInWindow(); // so can't add text to text components
         glassPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
      } else {
         System.out.println("done");
         glassPane.setCursor(Cursor.getDefaultCursor());
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("WaitCursor2");
      WaitCursor2 mainPanel = new WaitCursor2((JComponent) frame.getGlassPane());

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

The glass pane will trap mouse events if it set visible and given a MouseListener. It will lose t his ability if it is set invisible. Likewise it will pull the caret from text components if you make it focusable and give it focus.

这篇关于等待光标并禁用Java应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆