View Javadoc
1   /*******************************************************************************
2    * Copyhacked (H) 2012-2025.
3    * This program and the accompanying materials
4    * are made available under no term at all, use it like
5    * you want, but share and discuss it
6    * every time possible with every body.
7    * 
8    * Contributors:
9    *      ron190 at ymail dot com - initial implementation
10   ******************************************************************************/
11  package com.jsql.view.swing.popupmenu;
12  
13  import com.jsql.util.I18nUtil;
14  import com.jsql.util.LogLevelUtil;
15  import com.jsql.view.swing.text.JTextAreaPlaceholderConsole;
16  import com.jsql.view.swing.text.JTextPanePlaceholderConsole;
17  import com.jsql.view.swing.util.I18nViewUtil;
18  import org.apache.logging.log4j.LogManager;
19  import org.apache.logging.log4j.Logger;
20  
21  import javax.swing.*;
22  import javax.swing.event.PopupMenuEvent;
23  import javax.swing.event.PopupMenuListener;
24  import javax.swing.text.DefaultEditorKit;
25  import javax.swing.text.JTextComponent;
26  import java.awt.*;
27  import java.awt.event.ActionEvent;
28  import java.awt.event.InputEvent;
29  import java.awt.event.KeyEvent;
30  
31  /**
32   * Popup menu for editable text component.
33   */
34  public class JPopupMenuComponent extends JPopupMenu {
35      
36      private static final Logger LOGGER = LogManager.getRootLogger();
37      
38      private final JTextComponent component;
39      
40      /**
41       * Create a popup menu for editable component.
42       * @param component The component with the new menu
43       */
44      public JPopupMenuComponent(JTextComponent component) {
45          this.component = component;
46          
47          JMenuItem copyItem = new JMenuItem(component.getActionMap().get(DefaultEditorKit.copyAction));
48          copyItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK));
49          copyItem.setMnemonic('C');
50          copyItem.setText(I18nUtil.valueByKey("CONTEXT_MENU_COPY"));
51          I18nViewUtil.addComponentForKey("CONTEXT_MENU_COPY", copyItem);
52  
53          JMenuItem selectAllItem = new JMenuItem(component.getActionMap().get(DefaultEditorKit.selectAllAction));
54          selectAllItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
55          selectAllItem.setMnemonic('A');
56          selectAllItem.setText(I18nUtil.valueByKey("CONTEXT_MENU_SELECT_ALL"));
57          I18nViewUtil.addComponentForKey("CONTEXT_MENU_SELECT_ALL", selectAllItem);
58          
59          this.setLightWeightPopupEnabled(false);
60          
61          this.add(copyItem);
62          this.addSeparator();
63          this.add(selectAllItem);
64          
65          if (
66              component instanceof JTextAreaPlaceholderConsole
67              || component instanceof JTextPanePlaceholderConsole
68          ) {
69              JMenuItem clearItem = new JMenuItem();
70              clearItem.setAction(new AbstractAction() {
71                  @Override
72                  public void actionPerformed(ActionEvent e) {
73                      JPopupMenuComponent.this.component.setText(null);
74                  }
75              });
76              
77              clearItem.setText(I18nUtil.valueByKey("CONTEXT_MENU_CLEAR"));
78              I18nViewUtil.addComponentForKey("CONTEXT_MENU_CLEAR", clearItem);
79              clearItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK));
80              clearItem.setMnemonic('E');
81              
82              this.addSeparator();
83              this.add(clearItem);
84          }
85  
86          this.addPopupMenuListener(new PopupMenuOrientedListener());
87      }
88      
89      private class PopupMenuOrientedListener implements PopupMenuListener {
90          @Override
91          public void popupMenuWillBecomeVisible(PopupMenuEvent event) {
92              // Fix #47018: NullPointerException on getLocation()
93              try {
94                  JPopupMenuComponent.this.setLocation(MouseInfo.getPointerInfo().getLocation());
95                  JPopupMenuComponent.this.setLocation(
96                      ComponentOrientation.RIGHT_TO_LEFT.equals(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()))
97                      ? MouseInfo.getPointerInfo().getLocation().x - JPopupMenuComponent.this.getWidth()
98                      : MouseInfo.getPointerInfo().getLocation().x,
99                      MouseInfo.getPointerInfo().getLocation().y
100                 );
101             } catch (NullPointerException e) {
102                 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
103             }
104         }
105         @Override
106         public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
107             // Do nothing
108         }
109         @Override
110         public void popupMenuCanceled(PopupMenuEvent e) {
111             // Do nothing
112         }
113     }
114 }