powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Всплывающее меню для JTextComponent
3 сообщений из 3, страница 1 из 1
Всплывающее меню для JTextComponent
    #33822259
Фотография Penkov Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как извество, у компонент JTextComponent (типа JTextField, JTextArea итд), при нажатии на них правой кнопкой мыши, не появляется всплывающее окно с пунктами "копировать", "вставить", "вырезать" и "отменить". Вот класс, который решает эту проблему:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
 import  javax.swing.*;
 import  javax.swing.undo.UndoManager;
 import  javax.swing.text.JTextComponent;
 import  javax.swing.text.Document;
 import  java.util.HashMap;
 import  java.util.List;
 import  java.util.Iterator;
 import  java.awt.event.*;
 import  java.awt.datatransfer.Clipboard;
 import  java.awt.datatransfer.Transferable;
 import  java.awt.datatransfer.DataFlavor;
 import  java.awt.*;

/**
 * Created by IntelliJ IDEA.
 * User: Deady
 * Date: 29.06.2006
 * Time: 12:15:55
 */
 public   class  DocumentUndoManager {

     private   static  DocumentUndoManager instanse;
     private  UndoActionListener listener;
     private  HashMap items =  new  HashMap();
     private  EditPopup popup;

     private  DocumentUndoManager() {

        listener =  new  UndoActionListener();
        popup =  new  EditPopup();
    }

     public   static  DocumentUndoManager getInstance() {
         if  (instanse== null ) {
            instanse =  new  DocumentUndoManager();
        }
         return  instanse;
    }


     public   void  registerDocumentHolder(JTextComponent documentHolder) {
        //создаем новый менеджер изменений документа
        UndoManager undo =  new  UndoManager();
        //запоминаем его для данного текстового поля
        items.put(documentHolder, undo);
        //получаем модель документа такстового поля
        Document doc = documentHolder.getDocument();
        //добавляем слушатель изменений документа
        doc.addUndoableEditListener(undo);
        //добавляем слушатель нажатий клавиш (он будет обрабатывать ctrl+z)
        documentHolder.addKeyListener(listener);
        //добавляем слушатель нажатий кнопок мыши (он обработает нажатие правой кнопки)
        documentHolder.addMouseListener( new  MouseAdapter() {
             public   void  mouseClicked(MouseEvent e) {
                //если нажата правая кнопка мыши
                 if  (e.getButton()==MouseEvent.BUTTON3) {
                //if (e.isPopupTrigger()) { // <-- в линуксе (Fedora Core 5, KDE 3.5.3) это не работает
                    //устанавливаем текстовый компонент для меню
                    popup.setDocumentHolder((JTextComponent) e.getSource());
                    //отображаем всплывающее меню
                    popup.show((JTextComponent)e.getSource(), e.getX(), e.getY());
                }
            }
        });
    }

    /**
     * очищает историю изменений для текстовых компонент
     * @param documentHolders список компонент (из JTextComponent)
     */
     public   void  clearChangeHistory(List documentHolders) {
         for  (Iterator iterator = documentHolders.iterator(); iterator.hasNext();) {
            JTextComponent textComponent = (JTextComponent) iterator.next();
            UndoManager manager = (UndoManager) items.get(textComponent);
            manager.discardAllEdits();
        }
    }


     class  EditPopup  extends  JPopupMenu {


         private  JMenuItem copy;
         private  JMenuItem cut;
         private  JMenuItem paste;
         private  JMenuItem undo;
         private  JTextComponent documentHolder =  null ;


         public  EditPopup() {

            copy =  new  JMenuItem("Копировать");
            copy.addActionListener( new  ActionListener() {
                 public   void  actionPerformed(ActionEvent e) {
                     if  (documentHolder!= null ) {
                        documentHolder.copy();
                    }
                }
            });

            cut =  new  JMenuItem("Вырезать");
            cut.addActionListener( new  ActionListener() {
                 public   void  actionPerformed(ActionEvent e) {
                     if  (documentHolder!= null ) {
                        documentHolder.cut();
                    }
                }
            });

            paste =  new  JMenuItem("Вставить");
            paste.addActionListener( new  ActionListener() {
                 public   void  actionPerformed(ActionEvent e) {
                     if  (documentHolder!= null ) {
                        documentHolder.paste();
                    }
                }
            });

            undo =  new  JMenuItem("Отмена");
            undo.addActionListener( new  ActionListener() {
                 public   void  actionPerformed(ActionEvent e) {
                     if  (documentHolder!= null ) {
                        UndoManager manager = (UndoManager) items.get(documentHolder);
                         if  (manager.canUndo()) {
                            manager.undo();
                        }
                    }
                }
            });

            add(copy);
            add(cut);
            add(paste);
            addSeparator();
            add(undo);
        }


         public   void  setDocumentHolder(JTextComponent documentHolder) {
             this .documentHolder = documentHolder;
            //устанавливаем доступность пунктов "копировать" и "вырезать"
             if  (documentHolder.getSelectedText()!=  null  && documentHolder.getSelectedText()!=  null ) {
                copy.setEnabled(true);
                cut.setEnabled(true);
            }
             else  {
                copy.setEnabled(false);
                cut.setEnabled(false);
            }

            //устанавливаем доступность пункта "вставить"
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            Transferable contents = clipboard.getContents( this );
            DataFlavor flavor = DataFlavor.stringFlavor;
             if  (contents!= null  && contents.isDataFlavorSupported(flavor)) {
                paste.setEnabled(true);
            }
             else  {
                paste.setEnabled(false);
            }

            //устанавливаем доступность пункта "отмена"
            UndoManager manager = (UndoManager) items.get(documentHolder);
             if  (manager.canUndo()) {
                undo.setEnabled(true);
            }
             else  {
                undo.setEnabled(false);
            }

        }

    }


     class  UndoActionListener  extends  KeyAdapter {

         public   void  keyPressed(KeyEvent e) {

             if  (e.getKeyCode() == KeyEvent.VK_Z && e.isControlDown()) {
                UndoManager manager = (UndoManager) items.get(e.getSource());
                 if  (manager.canUndo()) {
                    manager.undo();
                }
            }

        }
    }
}



пользоваться им просто: каждое текстовое поле, для которого нужно показывать всплывающее меню, регистрируется в менеджере:

Код: plaintext
1.
2.
3.
        DocumentUndoManager undo = DocumentUndoManager.getInstance();
        undo.registerDocumentHolder(textfield1);
        undo.registerDocumentHolder(textfield2);

после этого будет появляться меню.
для каждого поля ведется лог изменений. Если необходимо для какого-то поля сбросить лог, вызывается метод clearChangeHistory, параметром ему передается список тех полей, для которых нужно сбросить лог.

Код: plaintext
1.
2.
3.
4.
5.
6.
            DocumentUndoManager undo = DocumentUndoManager.getInstance();
            List textHolders =  new  ArrayList();
            textHolders.add(textfield1);
            textHolders.add(textfield2);
            undo.clearChangeHistory(textHolders);



все. можно в faq.
...
Рейтинг: 0 / 0
Всплывающее меню для JTextComponent
    #33822269
Фотография Penkov Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл добавить. менеджер еще добавляет возможность отменить изменения, нажав ctrl+z.
...
Рейтинг: 0 / 0
Всплывающее меню для JTextComponent
    #33822426
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
instance смотрится красивее instаnse :)
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Всплывающее меню для JTextComponent
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]