понедельник, 8 апреля 2013 г.

Контекстное меню с командами вырезать, копировать, вставить, выделить всё для JTextComponent на java

В этой статье я хочу привести пример всплывающего по щелчку правой клавишей мыши меню с командами вырезать, копировать, вставить, выделить всё. Данное меню выполнено в виде класса, реализующего интерфейс MouseListener, для использования его следует просто добавить к компоненту расширяющему JTextComponent (JTextField, JEditorPane и т.д.) методом addMouseListener(). Ненужные команды меню автоматически скрываются, отображаются только те, выполнение которых возможно с текущим компонентом в текущем состоянии. Если никакие команды не могут быть выполнены, меню попросту не отображается.

package rva.common.gui.mouse;

import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Action;
import javax.swing.JPopupMenu;
import javax.swing.text.JTextComponent;

/**
 * MouseListener c командами копировать, вырезать, вставить, выделить все - для JTextComponent
 * @author Cloud
 */
public class ContextMenuMouseListener extends MouseAdapter {

    private final static String CUTTEXT = "Вырезать";
    private final static String SELECTAllTEXT = "Выделить все";
    private final static String COPYTEXT = "Копировать";
    private final static String PASTETEXT = "Вставить";

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getModifiers() == InputEvent.BUTTON3_MASK) {
            if (!(e.getSource() instanceof JTextComponent)) {
                return;
            }

            JTextComponent textComponent = (JTextComponent) e.getSource();
            textComponent.requestFocus();
            boolean enabled = textComponent.isEnabled();
            boolean editable = textComponent.isEditable();
            boolean nonempty = !(textComponent.getText() == null || textComponent.getText().equals(""));
            boolean marked = textComponent.getSelectedText() != null;

            boolean pasteAvailable =
                    Toolkit.getDefaultToolkit().getSystemClipboard().
                    getContents(null).isDataFlavorSupported(
                    DataFlavor.stringFlavor);

            JPopupMenu popup = new JPopupMenu();

            if (enabled && editable && marked) {
                Action cutAction = textComponent.getActionMap().get(DefaultEditorKit.cutAction);
                if (cutAction == null) {
                    cutAction = textComponent.getActionMap().get("cut");
                }
                if (cutAction != null) {
                    popup.add(cutAction).setText(CUTTEXT);
                }
            }
            if (enabled && marked) {
                Action copyAction = textComponent.getActionMap().get(DefaultEditorKit.copyAction);
                if (copyAction == null) {
                    copyAction = textComponent.getActionMap().get("copy");
                }
                if (copyAction != null) {
                    popup.add(copyAction).setText(COPYTEXT);
                }
            }
            if (enabled && editable && pasteAvailable) {
                Action pasteAction = textComponent.getActionMap().get(DefaultEditorKit.pasteAction);
                if (pasteAction == null) {
                    pasteAction = textComponent.getActionMap().get("paste");
                }
                if (pasteAction != null) {
                    popup.add(pasteAction).setText(PASTETEXT);
                }
            }

            if (enabled && nonempty) {
                Action selectAllAction = textComponent.getActionMap().get(DefaultEditorKit.selectAllAction);
                if (selectAllAction == null) {
                    selectAllAction = textComponent.getActionMap().get("selectAll");
                }
                if (selectAllAction != null) {
                    if (popup.getComponentCount() > 0) {
                        if (!(popup.getComponent(popup.getComponentCount() - 1) instanceof JPopupMenu.Separator)) {
                            popup.addSeparator();
                        }
                    }
                    popup.add(selectAllAction).setText(SELECTAllTEXT);
                }

            }

            if (popup.getComponentCount() > 0) {
                if (popup.getComponent(0) instanceof JPopupMenu.Separator) {
                    popup.remove(0);
                }
                if (popup.getComponent(popup.getComponentCount() - 1) instanceof JPopupMenu.Separator) {
                    popup.remove(popup.getComponentCount() - 1);
                }
               

                popup.show(e.getComponent(), e.getX(), e.getY() - popup.getSize().height);
            }
        }
    }
}

Вышепреведенное меню обычно имеет смысл добавить ко всем текстовым компонентам приложения. Сделать это можно следующим рекурсивным методом (после инициализации всех компонентов).
private static void iterateAllInterfaceComponentsAndAddContextMenuMouseListener(
       Component component) {
    if (component instanceof JTextComponent) {
       ((JTextComponent)component).addMouseListener(new ContextMenuMouseListener());
    }
    if (component instanceof Container) {
        for (Component c : ((Container) component).getComponents()) {
            iterateAllInterfaceComponentsAndAddContextMenuMouseListener(c);
        }
    }
}

6 комментариев:

  1. Анонимный12 мая 2014 г., 05:54

    А можно пример в коде по рекурсивному методу? А то у меня не работает. ContextMenuMouseListener отдельно работает, а iterateAllInterfaceComponentsAndAddContextMenuMouseListener нет.

    ОтветитьУдалить
    Ответы
    1. да, конечно
      public class SomeFrame extends javax.swing.JFrame {
      public SomeFrame () {
      // creation of content of frame
      // .....
      // call of the method (passing JFrame instance as parameter)
      iterateAllInterfaceComponentsAndAddContextMenuMouseListener(this);
      }
      }

      Удалить
  2. Анонимный12 мая 2014 г., 11:10

    Отлично. Спасибо. Всё работает.

    ОтветитьУдалить

Ярлыки

java (28) оптимизация (7) CPanel (5) svn (5) windows xp (5) ошибка (5) свой сервер (5) файлы и папки (5) gui (4) регулярные выражения (4) redmine (3) windows (3) автоматизация (3) защита данных (3) резервное копирование (3) сервер (3) JavaScript (2) Oracle SQL (2) adsl модем (2) apache tomcat (2) dropbox (2) excel (2) firewall (2) netbeans (2) office 2007 (2) samsung (2) system tray (системный трей) (2) xerox (2) вирусы (2) принтер (2) сериализация (2) удаленный рабочий стол (2) HTML (1) JFileChooser (1) MySQL (1) Nokia (1) Ovi (1) P660R-T1 (1) WakeOnLan (1) blogger.com (1) ctfmon.exe (1) email (1) flash память (1) ftp (1) ip (1) jQuery (1) jvisualWm (1) log4j (1) look and feel (1) myBatis (1) php (1) serialVersionUID (1) skype (1) smtp (1) ssh (1) swing (1) torrents (1) unix (1) vpn (1) windows 7 (1) xStarter (1) zip (1) безопасность (1) вход в систему (1) дизайн (1) документация (1) заправка (1) интернет (1) логирование (1) мышь (1) патч (1) перенос (1) печать (1) плагины (1) почтовые сообщения (1) программирование (1) процессы (1) прошивка (1) сеть (1) сеть. ошибка (1) скрытые файлы (1) списки (1) фильтрация (1) фокус (1) часовые пояса (1) шифрование (1) экран (1)