【问题标题】:Java Swing: Is it possible to make a component visible by user but transparent to mouse clicks?Java Swing:是否可以使组件对用户可见但对鼠标单击透明?
【发布时间】:2013-11-25 13:25:13
【问题描述】:

我有一个编辑器项目,在编辑器面板中我有一些用户可调整大小和可移动的面板。我通过一个单独的类 Resizable.java 定义了这些面板,该类扩展了 JComponent。我正在使用 MouseInputListener,所以当用户点击 Resizable 时,他可以移动或调整它的大小。当我将 jPanel 放入其中时,我仍然可以设法移动/调整它的大小。另一方面,如果我将 JTextArea 放入 Resizable 中,我将无法再进行操作,因为 JTextArea 会阻止我在 Resizable 上单击鼠标。我的意图是用户只有双击它才能编辑 JTextArea,否则他应该移动/调整面板的大小。 (就像adobe flash/photoshop/fireworks中的文字工具)

我尝试为 JTextArea 设置焦点(假)但没有成功。

有谁知道这样做的方法吗?还是更好的实现?

对不起我的英语,我希望我说清楚了。

谢谢。

【问题讨论】:

    标签: java swing jtextarea resizable


    【解决方案1】:

    您可以使用玻璃窗格来捕获鼠标事件。 Swing Tutotrial 有一个很好的例子,这里有一个玻璃窗格和鼠标事件:

    http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html

    另一种选择是将JTextArea 放在JInternalFrame 上的JDesktop 上。这将允许用户移动和调整它的大小,而不必弄乱鼠标事件。它的 UI 也会更直观。

    【讨论】:

      【解决方案2】:

      我的意图是用户只有双击它才能编辑 JTextArea,否则他应该移动/调整面板大小。

      创建文本区域时,您需要从文本区域中删除 MouseListener 和 MouseMotionListener。比如:

      MouseMotionListener[] mml = (MouseMotionListener[])textArea.getListeners(MouseMotionListener.class);
      
      for (int i = 0; i < actions.length; i++)
          textArea.removeMouseMotionListener( mml[i] );
      

      然后你需要安装你自己的自定义 MouseListener 来处理双击。当您收到双击事件时,您将需要删除您的 MouseListeners 并重新安装默认的 MouseListeners。

      然后,当您完成对文本区域的编辑后,您需要移除默认侦听器并将您的自定义侦听器添加回文本区域。

      【讨论】:

      • 你调整组件的大小可能会更接近(如删除并稍后添加侦听器)
      【解决方案3】:

      感谢jzd,我终于完成了我想要的。我没有使用玻璃窗格,但我基于相同的想法编写了一个实现。

      首先,我创建了 myTextTool 类,它扩展了 JTextArea 并覆盖了 MouseListeners 和 MouseMotionListeners。我在 myTextTool 类中保留了一个布尔变量 nowEditable,它指示用户尝试编辑或移动/调整大小。在 mouselistener 方法中,我检查了 nowEditable;如果是真的,则使 myTextTool 可编辑。如果它是假的,那么寻找双击。如果发生双击,则将 nowEditable 设置为 true,否则将 mouseevent 重定向到 Resizable 类。

      以下是处理和重定向鼠标事件的代码:

      private void redirectMouseEvent(MouseEvent e) {
      parentResizable.dispatchEvent(new MouseEvent(parentResizable,
                                                       e.getID(),
                                                       e.getWhen(),
                                                       e.getModifiers(),
                                                       e.getPoint().x+4,
                                                       e.getPoint().y+4,
                                                       e.getClickCount(),
                                                       e.isPopupTrigger()));
      }
      
      
      MouseInputListener ortamListener = new MouseInputAdapter() {
          public void mouseMoved(MouseEvent me) {
              if(!nowEditable)
                  redirectMouseEvent(me);
          }
      
          public void mouseExited(MouseEvent mouseEvent) {
              if(!nowEditable)
                  redirectMouseEvent(mouseEvent);
          }
      
          boolean isAlreadyOneClick=false;
          public void mousePressed(MouseEvent me) {
              //Eğer belirli zaman önce tıklandıysa double click olarak algıla
              if (isAlreadyOneClick && !nowEditable) {
                  nowEditable=true;
                  setEditable( true );
                  getCaret().setVisible(true);        
                  isAlreadyOneClick = false;
              }
              //İlk kez tıklandığında ve aktif değilken
              else if(!isAlreadyOneClick && !nowEditable) {
                  isAlreadyOneClick = true;
                  java.util.Timer t = new java.util.Timer("doubleclickTimer",
                          false);
                  //Eğer yarım saniye içinde 2. kez basmaz ise double-click olarak
                  //alma
                  t.schedule(new java.util.TimerTask() {
      
                      @Override
                      public void run() {
                      isAlreadyOneClick = false;
                      }
                  }, 500);
      
                  //Arka kutuya ilet
                  redirectMouseEvent(me);
              }
              //Aktifken bir şey yapma
      
          }
      
          public void mouseDragged(MouseEvent me) {
              if(!nowEditable)
                  redirectMouseEvent(me);
           }
      
          public void mouseReleased(MouseEvent mouseEvent) {
              if(!nowEditable)
                  redirectMouseEvent(mouseEvent);
          }
      };
      

      感谢所有回答。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-07
        • 2014-11-23
        • 2015-12-31
        • 1970-01-01
        • 2010-10-03
        • 2012-02-08
        • 2013-03-26
        相关资源
        最近更新 更多