-4

私は問題があります。

私は持っていJFrameます。を作成しJDialogます。

ボタンJDialogが押されると、破棄され、電子メールが送信されます。同時に、JDialog不確定で表示される別のものが必要JProgressBarです。電子メールが送信されたら、JDialog破棄する (そして新しいものを作成する) か、その内容を変更する必要があります。

私はこれで数時間失敗しているので、彼(または彼女)が私が望むことを行う疑似コードを私に書くのに十分親切かどうかenyoneに尋ねています。

クラスに何を含める必要があるかSwingWorker(または、より良いと思われる場合はマルチスレッドを使用するか)、いつJDialog(s)を作成/破棄する必要があるか、および電子メール送信のどこに固執するかを確認するためだけに...

私はここで完成した解決策を求めていることを知っていますが、私は締め切りにあり、すでに何度も失敗しています...これは私の最後の手段でした...

4

2 に答える 2

12

私はあなたのために短い例を作りました。基本的に、JFramewitha ボタンが表示されます。

ここに画像の説明を入力

JButtonフレームの をクリックするとJDialog、別のJButton( Send Email ) が表示されます - これは電子メール ダイアログを表します。

ここに画像の説明を入力

のが押されるとJButton、が破棄され、プログレスバー(またはこの場合は単純な)を保持する新しい が作成されます。emailDialogemailDialogJDialogJLabel

ここに画像の説明を入力

次にSwingWorker、メールを送信dispose()するを作成して実行しJDialog、完了したら を作成して実行し、送信のJOptionPane成功を示すメッセージを表示します。

ここに画像の説明を入力

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Test {

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initComponents(frame);
        frame.setPreferredSize(new Dimension(300, 300));//testing purposes
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents(final JFrame frame) {

        final JDialog emailDialog = new JDialog(frame);
        emailDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        emailDialog.setLayout(new BorderLayout());

        JButton sendMailBtn = new JButton("Send Email");
        sendMailBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                //get content needed for email from old dialog

                //get rid of old dialog
                emailDialog.dispose();

                //create new dialog
                final JDialog emailProgressDialog = new JDialog(frame);
                emailProgressDialog.add(new JLabel("Mail in progress"));
                emailProgressDialog.pack();
                emailProgressDialog.setVisible(true);

                new Worker(emailProgressDialog).execute();

            }
        });

        emailDialog.add(sendMailBtn, BorderLayout.SOUTH);
        emailDialog.pack();

        JButton openDialog = new JButton("Open emailDialog");
        openDialog.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                emailDialog.setVisible(true);
            }
        });

        frame.getContentPane().add(openDialog);

    }
}

class Worker extends SwingWorker<String, Object> {

    private final JDialog dialog;

    Worker(JDialog dialog) {
        this.dialog = dialog;
    }

    @Override
    protected String doInBackground() throws Exception {

        Thread.sleep(2000);//simulate email sending

        return "DONE";
    }

    @Override
    protected void done() {
        super.done();
        dialog.dispose();
        JOptionPane.showMessageDialog(dialog.getOwner(), "Message sent", "Success", JOptionPane.INFORMATION_MESSAGE);

    }
}
于 2012-09-28T14:43:38.273 に答える
4

@David Kroukamp

サブスタンスL&Fからの出力(テスト目的でのEDTに関する不確実性があります)

run:
JButton openDialog >>> Is there EDT ??? == true
Worker started >>> Is there EDT ??? == false
waiting 30seconds 
Worker endeded >>> Is there EDT ??? == false
before JOptionPane >>> Is there EDT ??? == false
org.pushingpixels.substance.api.UiThreadingViolationException: 
     Component creation must be done on Event Dispatch Thread

と詳細についての別の200行

出力は"correct container created out of EDT"

ここに画像の説明を入力してください

別のL&Fで、Nimbusに問題があることをテストします。ほとんどの場合、SystemLokkAndFeelはEDTの大きな間違い(EDTとは非常に異なる感度)を気にしません。デフォルトでは、MetalはWindowsプラットフォームで問題がありません。 Java6の場合、例は2番目のベースでも機能します

編集

ニンバスも気にしない

ここに画像の説明を入力してください

コードから

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;

public class Test {

    public static void main(String[] args) throws Exception {
        try {
            for (UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    UIManager.getLookAndFeelDefaults().put("nimbusOrange", (new Color(127, 255, 191)));

                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
        } catch (InstantiationException ex) {
        } catch (IllegalAccessException ex) {
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                /*try {
                    UIManager.setLookAndFeel(
                            "org.pushingpixels.substance.api.skin.SubstanceOfficeBlue2007LookAndFeel");
                    UIManager.getDefaults().put("Button.font", new FontUIResource(new Font("SansSerif", Font.BOLD, 24)));
                    UIManager.put("ComboBox.foreground", Color.green);
                } catch (Exception e) {
                }*/
                new Test().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initComponents(frame);
        frame.setPreferredSize(new Dimension(300, 300));//testing purposes
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents(final JFrame frame) {

        final JDialog emailDialog = new JDialog(frame);
        emailDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        emailDialog.setLayout(new BorderLayout());
        JButton sendMailBtn = new JButton("Send Email");
        sendMailBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                //get content needed for email from old dialog
                //get rid of old dialog
                emailDialog.dispose();
                //create new dialog
                final JDialog emailProgressDialog = new JDialog(frame);
                emailProgressDialog.add(new JLabel("Mail in progress"));
                emailProgressDialog.pack();
                emailProgressDialog.setVisible(true);
                new Worker(emailProgressDialog, frame).execute();

            }
        });
        emailDialog.add(sendMailBtn, BorderLayout.SOUTH);
        emailDialog.pack();
        JButton openDialog = new JButton("Open emailDialog");
        openDialog.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("JButton openDialog >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());
                emailDialog.setVisible(true);
            }
        });
        frame.getContentPane().add(openDialog);
    }
}

class Worker extends SwingWorker<String, Object> {

    private final JDialog dialog;
    private final JFrame frame;

    Worker(JDialog dialog, JFrame frame) {
        this.dialog = dialog;
        this.frame = frame;
    }

    @Override
    protected String doInBackground() throws Exception {
        System.out.println("Worker started >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());
        System.out.println("waiting 30seconds ");
        Thread.sleep(30000);//simulate email sending
        System.out.println("Worker endeded >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());
        dialog.dispose();
        System.out.println("before JOptionPane >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());
        JOptionPane.showMessageDialog(frame, "Message sent", "Success", JOptionPane.INFORMATION_MESSAGE);
        System.out.println("before JOptionPane >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());
        return null;
    }
}
于 2012-09-28T16:14:22.650 に答える