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      /**
37       * Log4j logger sent to view.
38       */
39      private static final Logger LOGGER = LogManager.getRootLogger();
40      
41      private final JTextComponent component;
42      
43      /**
44       * Create a popup menu for editable component.
45       * @param component The component with the new menu
46       */
47      public JPopupMenuComponent(JTextComponent component) {
48          this.component = component;
49          
50          JMenuItem copyItem = new JMenuItem(component.getActionMap().get(DefaultEditorKit.copyAction));
51          copyItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK));
52          copyItem.setMnemonic('C');
53          copyItem.setText(I18nUtil.valueByKey("CONTEXT_MENU_COPY"));
54          I18nViewUtil.addComponentForKey("CONTEXT_MENU_COPY", copyItem);
55  
56          JMenuItem selectAllItem = new JMenuItem(component.getActionMap().get(DefaultEditorKit.selectAllAction));
57          selectAllItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
58          selectAllItem.setMnemonic('A');
59          selectAllItem.setText(I18nUtil.valueByKey("CONTEXT_MENU_SELECT_ALL"));
60          I18nViewUtil.addComponentForKey("CONTEXT_MENU_SELECT_ALL", selectAllItem);
61          
62          this.setLightWeightPopupEnabled(false);
63          
64          this.add(copyItem);
65          this.addSeparator();
66          this.add(selectAllItem);
67          
68          if (
69              component instanceof JTextAreaPlaceholderConsole
70              || component instanceof JTextPanePlaceholderConsole
71          ) {
72              JMenuItem clearItem = new JMenuItem();
73              clearItem.setAction(new AbstractAction() {
74                  @Override
75                  public void actionPerformed(ActionEvent e) {
76                      JPopupMenuComponent.this.component.setText(null);
77                  }
78              });
79              
80              clearItem.setText(I18nUtil.valueByKey("CONTEXT_MENU_CLEAR"));
81              I18nViewUtil.addComponentForKey("CONTEXT_MENU_CLEAR", clearItem);
82              clearItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK));
83              clearItem.setMnemonic('E');
84              
85              this.addSeparator();
86              this.add(clearItem);
87          }
88  
89          this.addPopupMenuListener(new PopupMenuOrientedListener());
90      }
91      
92      private class PopupMenuOrientedListener implements PopupMenuListener {
93          @Override
94          public void popupMenuWillBecomeVisible(PopupMenuEvent event) {
95              // Fix #47018: NullPointerException on getLocation()
96              try {
97                  JPopupMenuComponent.this.setLocation(MouseInfo.getPointerInfo().getLocation());
98                  JPopupMenuComponent.this.setLocation(
99                      ComponentOrientation.RIGHT_TO_LEFT.equals(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()))
100                     ? MouseInfo.getPointerInfo().getLocation().x - JPopupMenuComponent.this.getWidth()
101                     : MouseInfo.getPointerInfo().getLocation().x,
102                     MouseInfo.getPointerInfo().getLocation().y
103                 );
104             } catch (NullPointerException e) {
105                 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
106             }
107         }
108         @Override
109         public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
110             // Do nothing
111         }
112         @Override
113         public void popupMenuCanceled(PopupMenuEvent e) {
114             // Do nothing
115         }
116     }
117 }