2016-07-22 69 views
1

我有JFrameJFileChooser。需要有一個自定義導入按鈕,而不是默認文件選擇器操作按鈕。JFileChooser.getSelectedFile()在執行自定義動作按鈕時返回null

如果我使用自定義操作按鈕,JFileChooser.getSelectedFile()如果我在文件名稱文本框中輸入值返回null。而如果我點擊文件並點擊自定義導入,我可以得到我選擇的文件。

在這裏,我包括在樣本代碼重現這個

import java.awt.BorderLayout; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class FileChooserDemo extends JPanel 
          implements ActionListener { 
    private static final long serialVersionUID = 1L; 
    JFileChooser importFileChooser; 
    JFrame frame; 

    private void createAndShowGUI() { 
     //Create and set up the window. 
     frame = new JFrame("FileChooserDemo"); 

     JPanel inputJobDetailsPanel = new JPanel(new BorderLayout(0,5)); 

     importFileChooser = new JFileChooser(); 
     importFileChooser.setControlButtonsAreShown(false); 
     importFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); 
     importFileChooser.setMultiSelectionEnabled(false); 
     inputJobDetailsPanel.add(importFileChooser, BorderLayout.CENTER); 

     GridBagLayout importButtonPanelLayout = new GridBagLayout(); 
     importButtonPanelLayout.columnWidths = new int[] {150}; 
     importButtonPanelLayout.rowHeights = new int[] {30}; 

     JPanel importButtonPanel = new JPanel(); 
     importButtonPanel.setLayout(importButtonPanelLayout); 

     JButton importButton = new JButton("Custom Import"); 
     importButton.setActionCommand("import"); 
     importButton.addActionListener(this); 
     importButtonPanel.add(importButton, new GridBagConstraints()); 

     JButton OtherButton = new JButton("Other Action"); 
     OtherButton.setActionCommand("otherImport"); 
     OtherButton.addActionListener(this); 
     importButtonPanel.add(OtherButton, new GridBagConstraints()); 

     inputJobDetailsPanel.add(importButtonPanel, BorderLayout.PAGE_END); 

     frame.add(inputJobDetailsPanel); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new FileChooserDemo().createAndShowGUI(); 
      } 
     }); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     String command = e.getActionCommand(); 
     if(command.equals("import")) { 
      if(importFileChooser.getSelectedFile() == null) { 
       JOptionPane.showMessageDialog(frame, "You entered file name but getSelectedFile() return null"); 
      }else { 
       JOptionPane.showMessageDialog(frame, "Chosen File Name: " + importFileChooser.getSelectedFile().getName()); 
      } 
     }else { 
      JOptionPane.showMessageDialog(frame, "You clicked other action"); 
     } 

    } 
} 

O/P:

enter image description here

重現步驟:

  1. 運行應用程序
  2. 輸入一個有效的文件名稱N「文件名」文本框中
  3. 點擊自定義導入
  4. 現在你可以看到「您輸入文件名,但getSelectedFile()返回NULL」

注意:如果我用importFileChooser.setControlButtonsAreShown(true);

啓用默認操作按鈕

我可以得到getSelectedFile(),即使我在文本框中輸入,而不點擊文件。

其實我想寫一個自動化腳本,所以我只能通過「文件名」文本框輸入文件路徑。

任何想法通過getSelectedFile()獲取文件而不點擊文件?

+0

無法在Mac OS X上重現;選擇器UI沒有「文本框」。 – trashgod

+0

@trashgod:在這裏我包含了屏幕截圖。我可以在Windows和Linux中看到這種情況。 – Tamil

回答

1

最後我得到了預期的輸出。調用默認文件選擇器按鈕動作監聽器

@SuppressWarnings("serial") 
@Override 
public void actionPerformed(ActionEvent e) { 
    String command = e.getActionCommand(); 
    if(command.equals("import")) { 
     if(importFileChooser.getSelectedFile() == null) { 
      MetalFileChooserUI ui = (MetalFileChooserUI) importFileChooser.getUI(); 
      for(ActionListener a: ui.getDefaultButton(importFileChooser).getActionListeners()) { 
       a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null) { 
          //Nothing need go here, the actionPerformed method (with the above arguments) will trigger the respective listener 
        }); 
      } 
     } 

     if(importFileChooser.getSelectedFile() != null) { 
      JOptionPane.showMessageDialog(frame, "Chosen File Name: " + importFileChooser.getSelectedFile().getName()); 
     } 
     else { 
      JOptionPane.showMessageDialog(frame, "You entered file name but getSelectedFile() return null"); 
     } 
    } 
    else { 
     JOptionPane.showMessageDialog(frame, "You clicked other action"); 
    } 
} 
+0

不是毫無道理,儘管我更喜歡配件。一些限制被提及[這裏](http://stackoverflow.com/a/38566916/230513)。 – trashgod

1

因爲不是所有的看&感覺實現提供了在文本字段文件名直接進入*,你可能要考慮一個替代設計:

  • 減模式:如圖Providing an Accessory Component,您可以在面板上添加一個附件組件,並在其上添加更多控件,如在功能之間切換的複選框。確切的細節將取決於定製導入其他動作啓用的功能。

  • 更多模式:顯示後的模式對話用戶已批准特定部分。

中間方法建議here具有以下限制:

  1. 假設javax.swing.plaf.metal.MetalLookAndFeel

  2. ActionEvent:「如果任何特定ActionEvent實例的id參數不在範圍ACTION_FIRSTACTION_LAST一個明確的行爲會引起

  3. ActionEvent:」 A null命令字符串是合法的,但不推薦「。

*如com.apple.laf.AquaLookAndFeel

+0

感謝您考慮我的問題。但我無法明白你的觀點。我是否需要更改LookAndFeel? – Tamil

+0

我認爲這不會有幫助;而是轉向附件組件或模態對話框。 – trashgod

+0

我已經發布了我的答案,請您驗證並告訴我是否會導致任何其他問題。謝謝!!! – Tamil