2016-02-22 2 views
0

Я пытаюсь связать ярлык для JTable Это работает отлично для алфавитов, но не для ключей, как Insert, Delete, Space и т.д.KeyBinding не работает для некоторых клавиш, как Insert, Delete

Для Ex ниже код работающий на Ctrl+I или любой другой алфавит, но если я поеду за Ctrl+Insert, это не работает, почему это так?

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.KeyStroke; 
import javax.swing.table.DefaultTableModel; 

public class NewClass { 
public static void main(String args[]) { 

    try { 
     for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
      if ("Windows".equals(info.getName())) { 
       javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
     } 
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) { 
     java.util.logging.Logger.getLogger(NewClass.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } 

    java.awt.EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      JFrame frame = new JFrame(); 
      frame.setLayout(new BorderLayout()); 
      frame.add(new JScrollPane(createTable()), BorderLayout.CENTER); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setSize(400, 500); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     } 
    }); 
} 

public static JTable createTable() { 
    DefaultTableModel tmodel = new DefaultTableModel(3, 5); 
    JTable table = new JTable(tmodel); 
    table.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "Insert"); 
    //Not working for VK_INSERT or VK_DELETE or VK_SPACE 
    table.getActionMap().put("Insert", new AbstractAction() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("Insert Action"); 
     } 
    }); 
    return table; 
} 

} 

Update 1

Это не работает при использовании WHEN_IN_FOCUSED_WINDOW но работает нормально, если я иду на WHEN_FOCUSED или WHEN_ANCESTOR_OF_FOCUSED_COMPONENT

+0

'WHEN_IN_FOCUSED_WINDOW', кажется, работает с' 'VK_INSERT' и VK_DELETE' без modifers – MadProgrammer

+0

я могу увидеть' VK_DELETE' работы с 'KeyEvent.CTRL_DOWN_MASK' модификатора, но не' VK_INSERT' – MadProgrammer

+0

@MadProgrammer Да, но Есть ли необходимость связывать 'Ctrl + Insert' – Madhan

ответ

1
  • требуется WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, как Corect установка для фокусировки (скрыта за JScrolPane s JViewport)

JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT

компонент содержит (или) компонент, который имеет фокус. Эта карта ввода обычно используется для составного компонента - компонента , реализация которого зависит от дочерних компонентов. Например, для JTables делает все свои привязки, используя WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, так что если пользователь редактирует, клавиша со стрелкой (например) все еще изменяет выбранную ячейку.

  • тогда все KeyEvent комбинации из OPS вопросов и комментариев работает правильно меня в Win7/Win10, Java7/Java8, с удаляемой записи по MadProgrammer тоже (users_rep> 10k)

  • AFAIK есть restiction , с номерами модификаторов, если> 2, то CTRL + ALT + SHIFT + Whatever можно поймать из AWTEventListener или из очень сложной KeyListener

код для моделирования в форме SSCCE/MCVE

.

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.KeyStroke; 
import javax.swing.table.DefaultTableModel; 

public class NewClass { 

    public static void main(String args[]) { 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info 
        : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Windows".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException | InstantiationException | 
       IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(
        NewClass.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new JScrollPane(createTable()), BorderLayout.CENTER); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setSize(400, 500); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static JTable createTable() { 
     DefaultTableModel tmodel = new DefaultTableModel(3, 5); 
     JTable table = new JTable(tmodel); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.CTRL_MASK), "Insert"); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK), "Insert"); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), "Insert"); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "Insert"); 
     table.getActionMap().put("Insert", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Action from JTable"); 
      } 
     }); 
     return table; 
    } 
} 
+0

все еще не работает;) – MadProgrammer

+0

@MadProgrammer, не знаю, что происходит на вашей стороне, потому что Swing Action выпустило событие из Win7/Java7 и Win10/Java8 из (KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK), – mKorbel

+0

Вы связались со всеми вы привязываетесь к одному и тому же действию, как вы знаете, какие из них работали? – MadProgrammer

1

без выбора

Delete Action from JTable 
Insert Action from JTable 
Space Action from JTable 
I Action from JTable 

после клетка выбрана

Delete Action from JTable 
    Insert Action from JTable 
    Space Action from JTable 
    I Action from JTable 

из кода, для требуется корректность (в противном случае есть куча unfilteres событий, но завершается для целей тестирования) в test for CTRL & & Что бы ни было прессовано внутриAWTEventListener

import java.awt.AWTEvent; 
import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Toolkit; 
import java.awt.event.AWTEventListener; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.JViewport; 
import javax.swing.KeyStroke; 
import javax.swing.SwingUtilities; 
import javax.swing.table.DefaultTableModel; 

public class NewClass { 

    private JFrame frame = new JFrame(); 
    private DefaultTableModel tmodel = new DefaultTableModel(3, 5); 
    private JTable table = new JTable(tmodel); 

    public NewClass() { 
     frame.add(new JScrollPane(createTable()), BorderLayout.CENTER); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocation(150, 150); 
     frame.setVisible(true); 
     Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { 

      @Override 
      public void eventDispatched(AWTEvent event) { 
       if (event instanceof KeyEvent) { 
        KeyEvent ke = (KeyEvent) event; 
        Component comp = ke.getComponent(); 
        if (comp instanceof JTable) { 
         System.out.println(comp); 
        } else if (comp instanceof JScrollPane) { 
         System.out.println(comp); 
        } else if (comp instanceof JViewport) { 
         System.out.println(comp); 
        } else if (comp instanceof JFrame) { 
         System.out.println(comp); 
        } else { 
         System.out.println(comp); 
        } 
       } 
      } 
     }, AWTEvent.KEY_EVENT_MASK); 
    } 

    public JTable createTable() { 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.CTRL_MASK), "Delete"); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK), "Insert"); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), "Space"); 
     table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "I"); 
     table.getActionMap().put("Delete", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Delete Action from JTable"); 
      } 
     }); 
     table.getActionMap().put("Insert", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Insert Action from JTable"); 
      } 
     }); 
     table.getActionMap().put("Space", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Space Action from JTable"); 
      } 
     }); 
     table.getActionMap().put("I", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("I Action from JTable"); 
      } 
     }); 
     return table; 
    } 

    public static void main(String args[]) { 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info 
        : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Windows".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException | InstantiationException | 
       IllegalAccessException | 
       javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(
        NewClass.class.getName()).log(
          java.util.logging.Level.SEVERE, null, ex); 
     } 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new NewClass(); 
      } 
     }); 
    } 
} 
+0

Я получаю все, кроме ctrl + insert, MacOS 10.11.3 Java 8 – MadProgrammer

+0

please whats SwingUtilities.isDescendingИз из ctrl + insert из AWTEventListener это событие должно быть зарегистрировано и отправлено :-) – mKorbel

+0

для тестирования мой другой пост о KeyBindngs, возможно, CTRL + I используется для контейнера – mKorbel

1

код, сделанный Rob (camickr), распечатать KeyBindings (извините, у меня нет ссылки на его код и Darryls ...)

import java.awt.*; 
import java.awt.event.*; 
import java.io.*; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.border.*; 
import javax.swing.table.*; 
import javax.swing.filechooser.*; 

public class KeyBindings implements ItemListener { 

    private static final String PACKAGE = "javax.swing."; 
    private static final String[] COLUMN_NAMES = {"Action", "When Focused", 
     "When In Focused Window", "When Ancestor"}; 
    private static String selectedItem; 
    private JComponent contentPane; 
    private JMenuBar menuBar; 
    private JTable table; 
    private JComboBox comboBox; 
    private Hashtable<String, DefaultTableModel> models; 

    public KeyBindings() { 
     models = new Hashtable<String, DefaultTableModel>(); 
     contentPane = new JPanel(new BorderLayout()); 
     contentPane.add(buildNorthComponent(), BorderLayout.NORTH); 
     contentPane.add(buildCenterComponent(), BorderLayout.CENTER); 
     resetComponents(); 
    } 

    public JComponent getContentPane() { 
     return contentPane; 
    } 

    public JMenuBar getMenuBar() { 
     if (menuBar == null) { 
      menuBar = createMenuBar(); 
     } 
     return menuBar; 
    } 

    private JComponent buildNorthComponent() { 
     comboBox = new JComboBox(); 
     JLabel label = new JLabel("Select Component:"); 
     label.setDisplayedMnemonic('S'); 
     label.setLabelFor(comboBox); 
     JPanel panel = new JPanel(); 
     panel.setBorder(new EmptyBorder(15, 0, 15, 0)); 
     panel.add(label); 
     panel.add(comboBox); 
     return panel; 
    } 

    private String checkForUIKey(String key) { 
     if (key.endsWith("UI") && key.indexOf(".") == -1) { 
      String componentName = key.substring(0, key.length() - 2); 
      if (componentName.equals("PopupMenuSeparator") 
        || componentName.equals("ToolBarSeparator") 
        || componentName.equals("DesktopIcon")) { 
       return null; 
      } else { 
       return componentName; 
      } 
     } 
     return null; 
    } 

    private JComponent buildCenterComponent() { 
     DefaultTableModel model = new DefaultTableModel(COLUMN_NAMES, 0); 
     table = new JTable(model) { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public boolean isCellEditable(int row, int column) { 
       return false; 
      } 
     }; 
     table.setAutoCreateColumnsFromModel(false); 
     table.getColumnModel().getColumn(0).setPreferredWidth(200); 
     table.getColumnModel().getColumn(1).setPreferredWidth(200); 
     table.getColumnModel().getColumn(2).setPreferredWidth(200); 
     table.getColumnModel().getColumn(3).setPreferredWidth(200); 
     Dimension d = table.getPreferredSize(); 
     d.height = 350; 
     table.setPreferredScrollableViewportSize(d); 
     table.getTableHeader().setFocusable(true); 
     return new JScrollPane(table); 
    } 

    public void resetComponents() { 
     models.clear(); 
     Vector<String> comboBoxItems = new Vector<String>(50); 
     UIDefaults defaults = UIManager.getLookAndFeelDefaults(); 
     for (Object key : defaults.keySet()) { 
      String componentName = checkForUIKey(key.toString()); 
      if (componentName != null) { 
       comboBoxItems.add(componentName); 
      } 
     } 
     Collections.sort(comboBoxItems); 
     comboBox.removeItemListener(this); 
     comboBox.setModel(new DefaultComboBoxModel(comboBoxItems)); 
     comboBox.setSelectedIndex(-1); 
     comboBox.addItemListener(this); 
     comboBox.requestFocusInWindow(); 
     if (selectedItem != null) { 
      comboBox.setSelectedItem(selectedItem); 
     } 
    } 

    private JMenuBar createMenuBar() { 
     JMenuBar menuBar = new JMenuBar(); 
     menuBar.add(createFileMenu()); 
     menuBar.add(createLAFMenu()); 
     return menuBar; 
    } 

    private JMenu createFileMenu() { 
     JMenu menu = new JMenu("Application"); 
     menu.setMnemonic('A'); 
     menu.addSeparator(); 
     menu.add(new ExitAction()); 
     return menu; 
    } 

    private JMenu createLAFMenu() { 
     ButtonGroup bg = new ButtonGroup(); 
     JMenu menu = new JMenu("Look & Feel"); 
     menu.setMnemonic('L'); 
     String lafId = UIManager.getLookAndFeel().getID(); 
     UIManager.LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels(); 
     for (int i = 0; i < lafInfo.length; i++) { 
      String laf = lafInfo[i].getClassName(); 
      String name = lafInfo[i].getName(); 
      Action action = new ChangeLookAndFeelAction(laf, name); 
      JRadioButtonMenuItem mi = new JRadioButtonMenuItem(action); 
      menu.add(mi); 
      bg.add(mi); 
      if (name.equals(lafId)) { 
       mi.setSelected(true); 
      } 
     } 
     return menu; 
    } 

    @Override 
    public void itemStateChanged(ItemEvent e) { 
     String componentName = (String) e.getItem(); 
     changeTableModel(getClassName(componentName)); 
     selectedItem = componentName; 
    } 

    private String getClassName(String componentName) { 
     if (componentName.equals("TableHeader")) { 
      return PACKAGE + "table.JTableHeader"; 
     } else { 
      return PACKAGE + "J" + componentName; 
     } 
    } 

    private void changeTableModel(String className) { 
     DefaultTableModel model = models.get(className); 
     if (model != null) { 
      table.setModel(model); 
      return; 
     } 
     model = new DefaultTableModel(COLUMN_NAMES, 0); 
     table.setModel(model); 
     models.put(className, model); 
     JComponent component = null; 
     try {// Hack so I don't have to sign the jar file for usage in Java Webstart 
      if (className.endsWith("JFileChooser")) { 
       component = new JFileChooser(new DummyFileSystemView()); 
      } else { 
       Object o = Class.forName(className).newInstance(); 
       component = (JComponent) o; 
      } 
     } catch (Exception e) { 
      Object[] row = {e.toString(), "", "", ""}; 
      model.addRow(row); 
      return; 
     } 
     ActionMap actionMap = component.getActionMap(); 
     Object[] keys = actionMap.allKeys(); 
     if (keys == null) { 
      Object[] row = {"No actions found", "", "", ""}; 
      model.addRow(row); 
      return; 
     } 
     for (int i = 0; i < keys.length; i++) { 
      Object key = keys[i]; 
      if (key instanceof String) { 
       continue; 
      } else { 
       keys[i] = ""; 
      } 
     } 
     Arrays.sort(keys); 
     for (int i = 0; i < keys.length; i++) { 
      Object key = keys[i]; 

      if (key != "") { 
       Object[] row = {key, "", "", ""}; 
       model.addRow(row); 
      } 
     } 
     updateModelForInputMap(model, 1, 
       component.getInputMap(JComponent.WHEN_FOCUSED)); 
     updateModelForInputMap(model, 2, 
       component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)); 
     updateModelForInputMap(model, 3, 
       component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)); 
    } 

    private void updateModelForInputMap(TableModel model, int column, InputMap inputMap) { 
     if (inputMap == null) { 
      return; 
     } 
     KeyStroke[] keys = inputMap.allKeys(); 
     if (keys == null) { 
      return; 
     } 
     Hashtable<Object, String> actions = new Hashtable<Object, String>(keys.length); 
     for (int i = 0; i < keys.length; i++) { 
      KeyStroke key = keys[i]; 
      Object actionName = inputMap.get(key); 
      Object value = actions.get(actionName); 
      if (value == null) { 
       actions.put(actionName, key.toString().replace("pressed ", "")); 
      } else { 
       actions.put(actionName, value + ", " + key.toString().replace("pressed ", "")); 
      } 
     } 
     for (int i = 0; i < model.getRowCount(); i++) { 
      String o = actions.get(model.getValueAt(i, 0)); 
      if (o != null) { 
       model.setValueAt(o.toString(), i, column); 
      } 
     } 
    } 

    class ChangeLookAndFeelAction extends AbstractAction { 

     private static final long serialVersionUID = 1L; 
     private String laf; 

     protected ChangeLookAndFeelAction(String laf, String name) { 
      this.laf = laf; 
      putValue(Action.NAME, name); 
      putValue(Action.SHORT_DESCRIPTION, getValue(Action.NAME)); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      try { 
       JMenuItem mi = (JMenuItem) e.getSource(); 
       JPopupMenu popup = (JPopupMenu) mi.getParent(); 
       JRootPane rootPane = SwingUtilities.getRootPane(popup.getInvoker()); 
       Component c = rootPane.getContentPane().getComponent(0); 
       rootPane.getContentPane().remove(c); 
       UIManager.setLookAndFeel(laf); 
       KeyBindings bindings = new KeyBindings(); 
       rootPane.getContentPane().add(bindings.getContentPane()); 
       SwingUtilities.updateComponentTreeUI(rootPane); 
       rootPane.requestFocusInWindow(); 
      } catch (Exception ex) { 
       System.out.println("Failed loading L&F: " + laf); 
       System.out.println(ex); 
      } 
     } 
    } 

    class ExitAction extends AbstractAction { 

     private static final long serialVersionUID = 1L; 

     public ExitAction() { 
      putValue(Action.NAME, "Exit"); 
      putValue(Action.SHORT_DESCRIPTION, getValue(Action.NAME)); 
      putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_X)); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.exit(0); 
     } 
    } 

    class DummyFileSystemView extends FileSystemView { 

     @Override 
     public File createNewFolder(File containingDir) { 
      return null; 
     } 

     @Override 
     public File getDefaultDirectory() { 
      return null; 
     } 

     @Override 
     public File getHomeDirectory() { 
      return null; 
     } 
    } 

    private static void createAndShowGUI() { 
     KeyBindings application = new KeyBindings(); 
     JFrame.setDefaultLookAndFeelDecorated(true); 
     JFrame frame = new JFrame("Key Bindings"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setJMenuBar(application.getMenuBar()); 
     frame.getContentPane().add(application.getContentPane()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
     /*try { 
      SynthLookAndFeel laf = new SynthLookAndFeel(); 
      UIManager.setLookAndFeel(laf); 
      KeyBindings bindings = new KeyBindings(); 
     } catch (UnsupportedLookAndFeelException ex) { 
      Logger.getLogger(KeyBindings.class.getName()).log(Level.SEVERE, null, ex); 
     } */ 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 

       createAndShowGUI(); 
      } 
     }); 
    } 
} 
Смежные вопросы