I have a JList filled with entries that the native copy method can't handle. I have a method that effectively copies and formats the selected data in just the way I want and I want this method to be called when ctrl + c is used but unfortunately JList is already listing for those accelerator keys so when I set them for my copy function in my JMenu it doesn't work unless I give the JMeny focus. Is there anyway that I can make ctrl + c use my copy method instead of the native one other than having to click on the JMenu every time I want to copy something?
Start by taking a look at How to Use Key Bindings and How to Use Actions
Start by creating a Action
which describes what it does and how it does. In this case, you may need to supply the JList
from which you want to copy from (I'd have some kind of interface
which provided a simply "copy" method of some kind, but that's just me)
public class CopyAction extends AbstractAction {
private JList list;
public CopyAction(JList list) {
putValue(NAME, "Copy");
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK));
putValue(MNEMONIC_KEY, KeyEvent.VK_C);
putValue(SELECTED_KEY, "Copy stuff");
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("All your copies belong to us");
}
public JList getList() {
return list;
}
}
Now, add a key binding to a JList
, along with your Action
...
public class TestPane extends JPanel {
private JList listOfStuff;
public TestPane() {
setLayout(new BorderLayout());
listOfStuff = new JList();
add(new JScrollPane(listOfStuff));
CopyAction copyAction = new CopyAction(listOfStuff);
listOfStuff.getActionMap().put("copy", copyAction);
}
public JList getListOfStuff() {
return listOfStuff;
}
}
Now, you can use the Action
with buttons as well...
TestPane tp = new TestPane();
CopyAction copyAction = new CopyAction(tp.getListOfStuff());
JMenuBar mb = new JMenuBar();
JMenu menu = new JMenu("Edit");
mb.add(menu);
menu.add(copyAction);
JFrame frame = new JFrame("Testing");
frame.setJMenuBar(mb);
And a fully runnable example....
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public class CopyAction extends AbstractAction {
private JList list;
public CopyAction(JList list) {
putValue(NAME, "Copy");
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK));
putValue(MNEMONIC_KEY, KeyEvent.VK_C);
putValue(SELECTED_KEY, "Copy stuff");
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("All your copies belong to us");
}
public JList getList() {
return list;
}
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
TestPane tp = new TestPane();
CopyAction copyAction = new CopyAction(tp.getListOfStuff());
JMenuBar mb = new JMenuBar();
JMenu menu = new JMenu("Edit");
mb.add(menu);
menu.add(copyAction);
JFrame frame = new JFrame("Testing");
frame.setJMenuBar(mb);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JList listOfStuff;
public TestPane() {
setLayout(new BorderLayout());
listOfStuff = new JList();
add(new JScrollPane(listOfStuff));
CopyAction copyAction = new CopyAction(listOfStuff);
listOfStuff.getActionMap().put("copy", copyAction);
}
public JList getListOfStuff() {
return listOfStuff;
}
}
}