2015-09-07 16 views
0

我嘗試向JFormattedTextField添加「標準」剪切/複製/粘貼彈出菜單。Swing:JPopupMenu在JFormattedTextField上彈出時取消選擇文本

粘貼按預期工作,但剪切和複製 - 不。問題是在彈出菜單JFormattedTextField期間丟失了它的選擇。任何想法爲什麼發生這種情況,以及如何解決它?

我的代碼:

public class SwingTest { 
    public static void main(String[] args) { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setContentPane(new TestPanel()); 
     f.pack(); 
     f.setVisible(true); 
    } 

    public static class TestPanel extends JPanel { 
     public TestPanel(){ 
      JFormattedTextField field = new JFormattedTextField(" "); 
      JFormattedTextField component = field; 
      final JPopupMenu menu = new JPopupMenu(); 
      JMenuItem item; 
      item = new JMenuItem(new DefaultEditorKit.CopyAction()); 
      item.setText("Copy"); 
      item.setEnabled(component.getSelectionStart() != component.getSelectionEnd()); 
      menu.add(item); 
      item = new JMenuItem(new DefaultEditorKit.CutAction()); 
      item.setText("Cut"); 
      item.setEnabled(component.isEditable() && component.getSelectionStart() != component.getSelectionEnd()); 
      menu.add(item); 
      item = new JMenuItem(new DefaultEditorKit.PasteAction()); 
      item.setText("Paste"); 
      item.setEnabled(component.isEditable()); 
      menu.add(item); 

      field.setComponentPopupMenu(menu); 
      add(field, java.awt.BorderLayout.CENTER); 
     } 
    } 
} 

UPDATE:快速調查顯示,上面的代碼工作在不同的OS X(我的操作系統)和Windows(大多數評論者OS)。我正在尋找安全且跨平臺的方式來顯示彈出式窗口。

+0

哪裏代碼的行動,被執行? – Blip

+0

旁註.'border layout'不是jpanel的默認佈局管理器。你必須爲'TestPanel'設置佈局到邊界。 –

+0

似乎對我來說工作正常,但我不會禁用任何菜單項之前適用於該領域;) – MadProgrammer

回答

3

我不確定這是你的問題。但是,

如果你的問題是複製/剪切菜單被禁用,當你點擊右鍵時,它發生,因爲你設置可見性,當gui開始(構造函數).so沒有文本和剪切副本項目被禁用,他們永遠不會啓用。您應該添加一個偵聽器,並且在動作觸發時設置可見性。當您右鍵單擊菜單項時,您的條件將會顯示/隱藏。

例如

public class SwingTest { 

    public static void main(String[] args) { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setContentPane(new TestPanel()); 
     f.pack(); 
     f.setVisible(true); 
    } 

} 

class TestPanel extends JPanel { 

    public TestPanel() { 
     setLayout(new BorderLayout()); 
     JFormattedTextField field = new JFormattedTextField(" "); 
     JFormattedTextField component = field; 
     final JPopupMenu menu = new JPopupMenu(); 
     JMenuItem item1, item2, item3; 
     item1 = new JMenuItem(new DefaultEditorKit.CopyAction()); 
     item1.setText("Copy"); 

     menu.add(item1); 
     item2 = new JMenuItem(new DefaultEditorKit.CutAction()); 
     item2.setText("Cut"); 

     menu.add(item2); 
     item3 = new JMenuItem(new DefaultEditorKit.PasteAction()); 
     item3.setText("Paste"); 

     menu.add(item3); 
     menu.addPopupMenuListener(new PopupMenuListener() { 

      @Override 
      public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 
       item1.setEnabled(component.getSelectionStart() != component.getSelectionEnd()); 
       item2.setEnabled(component.isEditable() && component.getSelectionStart() != component.getSelectionEnd()); 
       item3.setEnabled(component.isEditable()); 
      } 

      @Override 
      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 
      } 

      @Override 
      public void popupMenuCanceled(PopupMenuEvent e) { 
      } 
     }); 
     field.setComponentPopupMenu(menu); 
     add(field, java.awt.BorderLayout.CENTER); 

    } 
} 

側面說明:

1)避免聲明的JPanel作爲一個靜若你沒有理由。使它作爲實例。

2)border layout不是jpanel的默認佈局管理器。您必須將佈局設置爲TestPanel的邊框。

在你的代碼

您面板的佈局是流佈局(默認),但你打電話

add(field, java.awt.BorderLayout.CENTER); 

糾正這一點,你需要設置邊界佈局這樣

setLayout(new BorderLayout()); 
+0

我的問題是不禁止複製/粘貼,但這個菜單項不起作用。如果我選擇放置文本字段中,選擇它並從彈出菜單「說」複製,什麼也沒有發生。我所看到的是,在彈出過程中,字段中的文本選擇正在清除。再一次,沒有在Windows上測試它。在OS X下,它按我描述的那樣工作。 – FoxyBOA

+0

@FoxyBOA嗯,你可以測試我的上面的示例代碼,並告訴它的工作?或不 ? –

+0

在Windows下測試。您修復了與Windows相關的問題。不幸的是,OS X的行爲不同。是的,我正在尋找通用的方式來顯示這個彈出窗口的Linux,OS X和Windows。 – FoxyBOA

相關問題