2016-07-22 7 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. を入力します有効なファイル名i n個のカスタムインポート]をクリックし
  3. テキストボックス「ファイル名」
  4. 今、あなたは見ることができます

注「あなたは、ファイル名が、getSelectedFile()の戻りヌルに入った」:私は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_FIRSTからACTION_LASTの範囲内にない場合は、不特定の動作が発生することになる

  3. ActionEvent:」nullコマンド文字列が合法ではなく、お勧め。」

*例えばcom.apple.laf.AquaLookAndFeel

+0

私の質問を考えてくれてありがとう。しかし、私はあなたのポイントを得ることができません。 LookAndFeelを変更する必要がありますか? – Tamil

+0

私はそれが助けになるとは思わない。代わりに、アクセサリコンポーネントまたはモーダルダイアログに移動します。 – trashgod

+0

私は自分の答えを掲載しました。これが他の問題を引き起こすかどうか確認してください。ありがとうございました!!! – Tamil

関連する問題