1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sourceforge.jpotpourri.gui.table;
21
22 import java.awt.Point;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.awt.event.KeyEvent;
26 import java.awt.event.KeyListener;
27 import java.awt.event.MouseAdapter;
28 import java.awt.event.MouseEvent;
29 import java.util.List;
30
31 import javax.swing.Icon;
32 import javax.swing.JMenuItem;
33 import javax.swing.JPopupMenu;
34 import javax.swing.JTable;
35 import javax.swing.SwingUtilities;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40
41
42
43 public class TableBodyContext extends MouseAdapter implements ActionListener, KeyListener {
44
45 private static final Log LOG = LogFactory.getLog(TableBodyContext.class);
46
47 private final JTable table;
48 private final JPopupMenu popupSingle = new JPopupMenu();
49 private final JPopupMenu popupMultiple = new JPopupMenu();
50 private final ITableBodyContextListener listener;
51
52 private int tableRowSelected = -1;
53 private boolean isKeyDown = false;
54 private boolean wasPopupShownSingle = false;
55
56 public TableBodyContext(
57 final JTable table,
58 final List<JMenuItem> popupItemsSingle,
59 final List<JMenuItem> popupItemsMultiple,
60 final ITableBodyContextListener listener) {
61 this.table = table;
62 this.listener = listener;
63 this.table.addMouseListener(this);
64 this.table.addKeyListener(this);
65
66 for (JMenuItem item : popupItemsSingle) {
67 if(item == null) {
68 this.popupSingle.addSeparator();
69 } else {
70 item.addActionListener(this);
71
72 this.popupSingle.add(item);
73 }
74 }
75
76 if(popupItemsMultiple != null) {
77 for (JMenuItem item : popupItemsMultiple) {
78 if(item == null) {
79 this.popupMultiple.addSeparator();
80 } else {
81 item.addActionListener(this);
82
83 this.popupMultiple.add(item);
84 }
85 }
86 }
87 }
88
89 public static JMenuItem newJMenuItem(
90 final List<JMenuItem> items,
91 final String label,
92 final String actionCommand
93 ) {
94 return newJMenuItem(items, label, actionCommand, null);
95 }
96
97
98
99
100 public static JMenuItem newJMenuItem(
101 final List<JMenuItem> items,
102 final String label,
103 final String actionCommand,
104 final Icon icon
105 ) {
106 JMenuItem item = (icon != null) ? new JMenuItem(label, icon) : new JMenuItem(label);
107 item.setActionCommand(actionCommand);
108 items.add(item);
109 return item;
110 }
111
112 public static void newJMenuSeparator(final List<JMenuItem> items) {
113 items.add(null);
114 }
115
116 @Override
117 public final void mousePressed(final MouseEvent event) {
118 LOG.debug("mousePressed(); button()=" + event.getButton() + "; isPopupTrigger=" + event.isPopupTrigger());
119
120
121
122
123 final boolean isRightButton = event.getButton() == MouseEvent.BUTTON3;
124
125 if(isRightButton) {
126
127
128
129
130 if(this.isKeyDown == true) {
131 LOG.debug("SwingUtilities says right button, but actual only (meta-)key is down :/");
132 return;
133 }
134
135 final int selectedRows = this.table.getSelectedRows().length;
136 final JPopupMenu popup;
137 if(selectedRows == 1) {
138 this.wasPopupShownSingle = true;
139 popup = this.popupSingle;
140 } else if(selectedRows > 1) {
141 this.wasPopupShownSingle = false;
142 popup = this.popupMultiple;
143 } else {
144 LOG.debug("selected rows: " + selectedRows + "; ignore right click");
145 return;
146 }
147
148 final Point pointRightClick =
149 SwingUtilities.convertPoint(event.getComponent(), event.getPoint(), this.table);
150 this.tableRowSelected = this.table.rowAtPoint(pointRightClick);
151 this.table.requestFocus();
152
153 popup.show(this.table, pointRightClick.x, pointRightClick.y);
154 }
155 }
156
157 public final void actionPerformed(final ActionEvent event) {
158 JMenuItem item = (JMenuItem) event.getSource();
159 LOG.debug("actionPerformed(cmd=" + item.getActionCommand() + "; row=" + this.tableRowSelected + "; " +
160 "selection=" + (this.wasPopupShownSingle ? "single" : "multiple") + ")");
161
162 if(event.getModifiers() == ActionEvent.META_MASK) {
163 LOG.debug("Ignoring performed action because modifier indicates that right button was clicked.");
164 return;
165 }
166
167 if(this.wasPopupShownSingle == true) {
168 this.listener.contextMenuClicked(item, this.tableRowSelected);
169 } else {
170 this.listener.contextMenuClickedMultiple(item, this.table.getSelectedRows());
171 }
172 }
173
174 @SuppressWarnings("unused")
175 public final void keyPressed(final KeyEvent event) {
176 this.isKeyDown = true;
177 }
178
179 @SuppressWarnings("unused")
180 public final void keyReleased(final KeyEvent event) {
181 this.isKeyDown = false;
182 }
183
184 @SuppressWarnings("unused")
185 public final void keyTyped(final KeyEvent event) {
186
187 }
188
189
190 }