Hi, I am trying to implement functionality similar to that in Firefox and Aim6 to allow a user to flip back and forth through tabs using Ctrl+Shift+Tab and Ctrl+Tab, respectively. I haven't been to get the application to respond. I've been able to set up shortcuts for JButton and JToggleButton using AbstractAction, but don't have that option with JTabbedPane. Here is my code for setting the shortcuts. As I am fairly new to writing keyboard shortcuts and using InputMap/ActionMap and the like, it may seem a little hacked-and-slashed together:
//I included some of the shortcuts that I've successfully implemented to give a better idea of what I'm trying to do
public class FrmMyInternalFrame extends FrmSuperInternalFrame {
.
.
.
//called in constructor after gui is built
protected void setupKeyboardShortcuts() {
Icon icoNewRecord = cmdAdd.getIcon();
KeyStroke ksAdd = KeyStroke.getKeyStroke(KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK);
KeyStroke ksSave = KeyStroke.getKeyStroke(KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK);
KeyStroke ksNextTab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, java.awt.event.InputEvent.CTRL_MASK);
KeyStroke ksPrevTab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
java.awt.event.InputEvent.CTRL_MASK & java.awt.event.InputEvent.SHIFT_MASK);
InputMap iMap = this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
iMap.put(ksAdd, icoNewRecord); //button has icon instead of text
iMap.put(ksSave, cmdSave.getText()); //button has text label
//I'm thinking that the second parameter in these two calls is part of the problem
iMap.put(ksNextTab, "Next Tab"); //prolly shouldn't use String literals since this is also referenced below
iMap.put(ksPrevTab, "Previous Tab"); //prolly shouldn't use String literals since this is also referenced below
//cmdSave is JButton that is inherited from superclass
cmdSave.setAction(new AbstractAction(iMap.get(ksSave).toString()) {
public void actionPerformed(ActionEvent ae) {
cmdSave_actionPerformed(ae); //abstract method inherited from super class, contains event handling code
}
});
//cmdAdd is JToggleButton that is inherited from superclass
cmdAdd.setAction(new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
cmdAdd_actionPerformed(ae); //abstract method inherited from super class, contains event handling code
}
});
AbstractAction aaNextTab = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
int nextIndex = tabPanel.getSelectedIndex() + 1;
if(nextIndex < tabPanel.getTabCount()) {
tabPanel.setSelectedIndex(nextIndex);
}
else {
tabPanel.setSelectedIndex(0);
}
}
};
AbstractAction aaPrevTab = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
int prevIndex = tabPanel.getSelectedIndex() - 1;
if(prevIndex >= 0) {
tabPanel.setSelectedIndex(prevIndex);
}
else {
tabPanel.setSelectedIndex(tabPanel.getTabCount() - 1);
}
}
};
//since no setAction() method for JTabbedPane, tried using ActionMap
ActionMap amTabs = tabPanel.getActionMap();
amTabs.put("Next Tab", aaNextTab);
amTabs.put("Previous Tab", aaPrevTab);
((AbstractAction) cmdAdd.getAction()).putValue(AbstractAction.SMALL_ICON, icoNewRecord);
this.getActionMap().put(iMap.get(ksSave), cmdSave.getAction());
this.getActionMap().put(iMap.get(ksAdd), cmdAdd.getAction());
this.getActionMap().put("Next Tab", tabPanel.getActionMap().get("Next Tab"));
this.getActionMap().put("Previous Tab", tabPanel.getActionMap().get("Previous Tab"));
// amTabs.setParent(this.getActionMap()); //tried this as replacement for previous 2 lines, but no luck
}
}
{code}
What do you guys think?