Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Всплывающее меню для JTextComponent / 3 сообщений из 3, страница 1 из 1
29.06.2006, 16:46
    #33822259
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всплывающее меню для JTextComponent
Как извество, у компонент 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
29.06.2006, 16:48
    #33822269
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всплывающее меню для JTextComponent
забыл добавить. менеджер еще добавляет возможность отменить изменения, нажав ctrl+z.
...
Рейтинг: 0 / 0
29.06.2006, 17:27
    #33822426
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всплывающее меню для JTextComponent
instance смотрится красивее instаnse :)
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Всплывающее меню для JTextComponent / 3 сообщений из 3, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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