Swing chaining JOptionPane into JFileChooser



我正在尝试使用Swing进行文件传输通知。这个想法是,当我的应用程序通过网络提供一个文件时,用户收到一个JOptionPane询问他或她是否想接受该文件提供,如果他们的答案是肯定的,我想打开一个JFileChooser,这样他们就可以浏览到他们想要保存文件的位置。

我遇到的问题是,两者单独工作都很好,但是当我设置它们时,JOptionPane打开JFileChooser,我的应用程序死锁。

有人知道这里出了什么问题吗?我试过调试,但没有发现任何奇怪的行为,可以说明为什么它会死锁。

编辑:下面的示例代码似乎工作得很好,让我相信问题可能在于另一个线程。进一步的细节:

我正在使用一个应用程序线程,ApplicationLayer线程和一个'Main'线程,主线程根据我定义的字符串生成一个字节数组,然后它将生成的字节数组通过我的ApplicationLayer发送到我的应用程序。

ApplicationLayer是一个Observable,而Application是它的Observer。

当ApplicationLayer接收到所述字节数组时,它将其解析回字符串,并通知它的观察者它已经这样做了。

然后依次通知应用程序。在我的例子中,应用程序注意到字符串是一个文件报价,并相应地调用'saveFile'方法,如下面的代码所示。

代码:

  package application;
    public class GUI extends JFrame implements ActionListener, ItemListener, Observer {
private JPanel cp = new JPanel();
private JPanel ulp = new JPanel();
private JTextField  myMessage;
private JTextArea   taMessages;
    // Menu Bar Elements
JMenuBar menuBar;
JMenu menu, submenu;
public GUI(){
    super();    
    this.setLayout(new BorderLayout());
    setPreferredSize(new Dimension(800, 600));
    setMinimumSize(new Dimension(800, 600));
    buildBarMenu();
    buildChatMenu();
    addWindowListener(new WindowAdapter() {
        public void windowClosing(final WindowEvent e) {
            e.getWindow().dispose();
        }
        public void windowClosed(final WindowEvent e) {
            System.exit(0);
        }
    }
            );
    pack();
    validate();
    setVisible(true);
}
    public static void main(final String[] args) {
    try {
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (Exception e) {
        // If Nimbus is not available, fall back to cross-platform
        try {
                     UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
        } catch (Exception ex) {
        }
    }
    new GUI();
    }
    private void buildBarMenu(){
    // Create the menu bar
    JMenuBar menuBar = new JMenuBar();
    // Create a menu
    JMenu menu = new JMenu("File");
    menu.setHorizontalTextPosition(SwingConstants.CENTER);
    menu.setVerticalTextPosition(SwingConstants.BOTTOM);
    menuBar.add(menu);
    // SendFile Item
    JMenuItem sendFileItem = new JMenuItem("Send File");
    sendFileItem.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e) {
            saveFile(); // Put whatever here
        }
    });
    // Exit item
    JMenuItem exitItem = new JMenuItem("Exit");
    exitItem.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    });
    menu.add(sendFileItem);
    menu.add(exitItem);
    this.setJMenuBar(menuBar);
    }
private void buildChatMenu() {
    this.add(cp, BorderLayout.CENTER);
    this.add(ulp, BorderLayout.EAST);
}
/**
 * Method to be called for saving files when a file transfer
 * request is received
 * @return the path to save the file to
 */
public String saveFile(){
    int choice = JOptionPane.showConfirmDialog(GUI.this, "You are being offered a file, accept?", "File Offer",
            JOptionPane.YES_NO_OPTION);
    if (choice == JOptionPane.YES_OPTION){
        System.out.println("yes");
        JFileChooser c = new JFileChooser();
        int rVal = c.showOpenDialog(GUI.this);
        if (rVal == JFileChooser.APPROVE_OPTION) {
        }
        if (rVal == JFileChooser.CANCEL_OPTION) {
        }
    }else{
        System.out.println("no");
    }
    return null;
}
public void save2(){
    JFileChooser c = new JFileChooser();

    int rVal = c.showOpenDialog(GUI.this);
    if (rVal == JFileChooser.APPROVE_OPTION) {
        System.exit(0);
    }
    if (rVal == JFileChooser.CANCEL_OPTION) {
        System.exit(0);
    }
}

@Override
public void itemStateChanged(ItemEvent e) {
    // TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
}
    @Override
public void update(Observable o, Object arg) {

    if(arg instanceof ChatMessage){
        cp.addMessage(((ChatMessage) arg).getNickname(), ((ChatMessage) arg).getMessage());
    }
    else if(arg instanceof FileOfferMessage){
        cp.addMessage("FILE OFFER", ((FileOfferMessage) arg).getFileName() + " | File Size: " + ((FileOfferMessage) arg).getFileSize() + " bytes");
        saveFile();
    }

}

   }

任何使用Swing组件的代码都必须在EventDispatchThread中运行。您的main()方法应该调用invokeLater,并在传递的Runnable中执行GUI操作(包括外观部分)。

注:这是在关闭窗口时退出应用程序的首选方式。

相关内容

  • 没有找到相关文章

最新更新