2016-03-10 4 views
1

Я создал небольшое приложение, использующее NetBeans 8.1 на OSX. Он содержит только два меню «файл» и «редактирование». Цель состоит в том, чтобы добавить дополнительные функции копирования/вырезания/вставки в меню редактирования позже. Я хочу использовать Netbeans GUI Builder, но я сталкиваются со следующими проблемами:Java на OSX: неправильный значок ключа ускорителя в меню Swing с помощью построителя GUI Netbeans

первая попытка:

Я создал небольшой пример с Netbeans GUI Builder (Swing GUI Forms -> JDialog). Я просто добавил панель меню в JFrame и JMenuItem в построителе GUI и некоторый код для конструктора. Результат:

enter image description here

Как вы можете видеть, я получаю текст «мета» вместо ключа от Apple ⌘.

Исходный код NewJDialogGUI.java:

import java.awt.Toolkit; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.KeyStroke; 
import javax.swing.text.DefaultEditorKit; 

public class NewJDialogGUI extends javax.swing.JDialog { 
    private static final int MASK 
     = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); 

    public NewJDialogGUI(java.awt.Frame parent, boolean modal) { 
     super(parent, modal); 

     initComponents(); 

     AbstractAction copyAction = new DefaultEditorKit.CopyAction(); 
     copyAction.putValue(Action.ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_C, MASK)); 


     this.jMenuItem1.setAction(copyAction); 
     this.jMenuItem1.setText("Copy"); 
     this.jMenuItem1.setMnemonic(KeyEvent.VK_C); 

    } 

    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code">       
    private void initComponents() { 

     jMenuBar1 = new javax.swing.JMenuBar(); 
     jMenu1 = new javax.swing.JMenu(); 
     jMenu2 = new javax.swing.JMenu(); 
     jMenuItem1 = new javax.swing.JMenuItem(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); 

     jMenu1.setText("File"); 
     jMenuBar1.add(jMenu1); 

     jMenu2.setText("Edit"); 

     jMenuItem1.setText("jMenuItem1"); 
     jMenu2.add(jMenuItem1); 

     jMenuBar1.add(jMenu2); 

     setJMenuBar(jMenuBar1); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 400, Short.MAX_VALUE) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 278, Short.MAX_VALUE) 
     ); 

     pack(); 
    }// </editor-fold>       


    public static void main(String args[]) { 
     /* Set the Nimbus look and feel */ 
     //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
     /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */ 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException ex) { 
      java.util.logging.Logger.getLogger(NewJDialogGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      java.util.logging.Logger.getLogger(NewJDialogGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      java.util.logging.Logger.getLogger(NewJDialogGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(NewJDialogGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 
     //</editor-fold> 

     /* Create and display the dialog */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       NewJDialogGUI dialog = new NewJDialogGUI(new javax.swing.JFrame(), true); 
       dialog.addWindowListener(new java.awt.event.WindowAdapter() { 
        @Override 
        public void windowClosing(java.awt.event.WindowEvent e) { 
         System.exit(0); 
        } 
       }); 
       dialog.setVisible(true); 
      } 
     }); 
    } 

    private javax.swing.JMenu jMenu1; 
    private javax.swing.JMenu jMenu2; 
    private javax.swing.JMenuBar jMenuBar1; 
    private javax.swing.JMenuItem jMenuItem1;     
} 

И NewJDialogGUI.form:

<?xml version="1.0" encoding="UTF-8" ?> 

<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> 
    <NonVisualComponents> 
    <Menu class="javax.swing.JMenuBar" name="jMenuBar1"> 
     <SubComponents> 
     <Menu class="javax.swing.JMenu" name="jMenu1"> 
      <Properties> 
      <Property name="text" type="java.lang.String" value="File"/> 
      </Properties> 
     </Menu> 
     <Menu class="javax.swing.JMenu" name="jMenu2"> 
      <Properties> 
      <Property name="text" type="java.lang.String" value="Edit"/> 
      </Properties> 
      <SubComponents> 
      <MenuItem class="javax.swing.JMenuItem" name="jMenuItem1"> 
       <Properties> 
       <Property name="text" type="java.lang.String" value="jMenuItem1"/> 
       </Properties> 
      </MenuItem> 
      </SubComponents> 
     </Menu> 
     </SubComponents> 
    </Menu> 
    </NonVisualComponents> 
    <Properties> 
    <Property name="defaultCloseOperation" type="int" value="2"/> 
    </Properties> 
    <SyntheticProperties> 
    <SyntheticProperty name="menuBar" type="java.lang.String" value="jMenuBar1"/> 
    <SyntheticProperty name="formSizePolicy" type="int" value="1"/> 
    <SyntheticProperty name="generateCenter" type="boolean" value="false"/> 
    </SyntheticProperties> 
    <AuxValues> 
    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> 
    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> 
    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> 
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> 
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> 
    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> 
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> 
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> 
    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> 
    </AuxValues> 

    <Layout> 
    <DimensionLayout dim="0"> 
     <Group type="103" groupAlignment="0" attributes="0"> 
      <EmptySpace min="0" pref="400" max="32767" attributes="0"/> 
     </Group> 
    </DimensionLayout> 
    <DimensionLayout dim="1"> 
     <Group type="103" groupAlignment="0" attributes="0"> 
      <EmptySpace min="0" pref="278" max="32767" attributes="0"/> 
     </Group> 
    </DimensionLayout> 
    </Layout> 
</Form> 

второй попробовать:

Я создал еще один небольшой пример с Netbeans GUI Builder (Swing GUI Forms -> Пример формы заявки). Результат:

enter image description here

Тот же результат, как и в 1-й попытки.

третья попытка:

Наконец я создал пример с Netbeans (пустой файл Java) с исходным кодом слегка модифицированный от here. Результат:

enter image description here

Исходный код:

import java.awt.EventQueue; 
import java.awt.Toolkit; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JMenuItem; 
import javax.swing.JTextField; 
import javax.swing.KeyStroke; 
import javax.swing.text.DefaultEditorKit; 

/** 
* @see https://stackoverflow.com/a/34830519/230513 
*/ 
public class NewEmptyGUI { 

    private static final int MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); 

    private void display() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JMenuBar menuBar = new JMenuBar(); 
     JMenu menu = new JMenu("Edit"); 
     menu.setMnemonic(KeyEvent.VK_E); 
     JMenuItem menuItem = new JMenuItem(); 
     AbstractAction copyAction = new DefaultEditorKit.CopyAction(); 
     copyAction.putValue(Action.ACCELERATOR_KEY, 
       KeyStroke.getKeyStroke(KeyEvent.VK_C, MASK)); 
     menuItem.setAction(copyAction); 
     menuItem.setText("Copy"); 
     menu.add(menuItem); 
     menuBar.add(menu); 
     f.setJMenuBar(menuBar); 
     f.add(new JTextField(10)); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 


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

      @Override 
      public void run() { 

       new NewEmptyGUI().display(); 
      } 
     }); 
    } 
} 

Это ожидаемый результат, но все меню infrastrucure кодировались вручную, что я не намерен. Я хочу использовать NetBeans GUI Builder. У вас есть какие-то намеки на меня?

Я использую JDK7 и OSX Yosemite. Внешний вид «Нимбус». Я только вставляю код примера или 1-й и 3-й попытки здесь, потому что это довольно много кода.

+0

Благодарим вас за [mcve]; добавление 'NewJDialogGUI.form' позволит другим воссоздать ваш пример. – trashgod

+0

Trashgod, приятно здесь от вас! Я обновил вопрос с помощью «NewJDialogGUI.form». – Bebass

ответ

1

Я нашел решения для описанной проблемы.

Решение 1 (Изменить внешний вид и):

В примере кода показано, как заменить «Nimbus выглядеть и чувствовать себя» в Netbeans созданный код.Он будет также установить правильные сочетания клавиш для буфера обмена действий, как копия & пасты с Apple, ключ «⌘» вместо «Control-Key» автоматически:

public static void main(String args[]) { 

    try { 
     for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
      /* 
      if ("Nimbus".equals(info.getName())) { 
       javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
      */ 
      if ("Mac OS X".equals(info.getName())) { 
       javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
     } 
    } catch (ClassNotFoundException ex) { 
     java.util.logging.Logger.getLogger(App_Avaprism.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (InstantiationException ex) { 
     java.util.logging.Logger.getLogger(App_Avaprism.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (IllegalAccessException ex) { 
     java.util.logging.Logger.getLogger(App_Avaprism.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
     java.util.logging.Logger.getLogger(App_Avaprism.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } 


    java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new App_Avaprism().setVisible(true); 
     } 
    }); 

Решение 2:

Если вы хотите оставаться с «нимбом» все усложняется. Сначала я не нашел возможности заменить текст «мета». По крайней мере, вы можете захотеть использовать ярлыки буфера обмена с ключом Apple «⌘».

Для вашего основного приложения поместите следующий код в конструктор:

int MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); 

InputMap im = (InputMap) UIManager.get("TextField.focusInputMap"); 
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, MASK), DefaultEditorKit.copyAction); 
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, MASK), DefaultEditorKit.pasteAction); 
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, MASK), DefaultEditorKit.cutAction); 

К сожалению: Если вы запускаете другие модальные диалоги из этого основного приложения короткие сокращения не будет работать. В этом случае вы можете попытаться использовать KeyEventDispatcher, чтобы установить глобальное перенаправление нажатий клавиш для всего приложения. Более подробную информацию об этом можно найти here и here.

+0

Решение '1' является значением по умолчанию, поэтому оно не нужно; решение '2' - это правильный способ сделать' com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel' использовать 'MASK', который' com.apple.laf.AquaLookAndFeel' использует по умолчанию; плюс один для полезных ресурсов. – trashgod

+0

Удивительно, что я нашел в генерации Netbeans код 'if (« Nimbus ».equals (info.getName())) вместо' if («Mac OS X» .equals (info.getName())), хотя Создатель GUI показал «aqua l & f» в предварительном просмотре, и я запускаю Netbeans под OSX. Итак, вы правы: он должен быть по умолчанию под OSX, но в моем случае это не так. Не могли бы вы проверить, что Netbeans генерирует в вашем случае по умолчанию? – Bebass

+0

А, я вижу разницу: 'com.apple.laf.AquaLookAndFeel' по умолчанию не имеет кода инициализации вообще, а код для установки' com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel' (если есть) является значением по умолчанию для сгенерированного кода. – trashgod

 Смежные вопросы

  • Нет связанных вопросов^_^