将JDIALog从MODELESS更改为APPLICATION_MODAL会打开JDialog两次

时间:2012-10-05 07:28:37

标签: java swing jdialog

我有一个非常奇怪的行为,我只能在某处确定Java bug。

我在构造函数中更改了一行

super(parent, "Production Plan Export", ModalityType.MODELESS);

super(parent, "Production Plan Export", ModalityType.APPLICATION_MODAL);

突然当我点击按钮打开我的JDialog时,它会打开两次,这是第一次,它根本没有响应。我需要单击X按钮关闭窗口,然后当我这样做时,会出现相同的JDialog,突然我的所有按钮都会打开。

之前有没有人见过这种行为?

我正在使用Java 1.6.0_33

修改 非常奇怪的是,当我尝试在eclipse中调试它并在我的构造器中设置断点时,我转到下一行,然后它突然跳转到类中的变量并开始通过我的变量而不是构造函数中的下一行。

我试图重新启动计算机并进行日食,但这不起作用。 我会看看我是否可以创建一个小测试用例

EDIT2:

好的,所以我创建了一个可以为我重现它的小应用程序。 请注意,我试图删除不相关的代码部分,因此有很多代码对此测试用例无效。

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class ProductionPlanExportDialog extends JDialog {

    private JProgressBar progressbar;
    private JLabel message;
    private JButton exportButton;
    private JButton helpButton;

    private int state = JOptionPane.CANCEL_OPTION;
    private final Action closeAction = new CloseAction();
    private final Action enableExport = new EnableExport();
    private boolean updating = false;

    private JButton closeButton;

    public ProductionPlanExportDialog(Window parent) {
        super(parent, "Test", ModalityType.APPLICATION_MODAL); //The JDialog is not centered, and the close button doesn't work
//      super(parent, "Test", ModalityType.MODELESS); //The close button works and the jdialog is centered
        initGUI();
        bindModel();

        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                close();
            }
        });
    }

    public static void main(String args[]) {
        new ProductionPlanExportDialog(null);
    }

    public void initGUI() {
        JTabbedPane mainTabbedPane = new JTabbedPane(JTabbedPane.TOP);

        JPanel yAxisPanel = new JPanel();
        yAxisPanel.setLayout(new BoxLayout(yAxisPanel, BoxLayout.Y_AXIS));


        JPanel progressPanel = new JPanel(new FlowLayout());
        progressPanel.add(getProgressbar());
        yAxisPanel.add(progressPanel);
        yAxisPanel.add(getMessage());

        JPanel buttonPanel = new JPanel(new FlowLayout()); 
        buttonPanel.add(getExportButton());
        closeButton = new JButton("Close");
        buttonPanel.add(closeButton);
        buttonPanel.add(getHelpButton());

        yAxisPanel.add(buttonPanel);

        setSize(937, 605);
        getContentPane().add(yAxisPanel);
        setVisible(true);
        setLocationRelativeTo(null);
    }

    private void bindModel() {
        closeButton.setAction(closeAction);
    }

    public int getExitStatus() {
        return state;
    }

    private JProgressBar getProgressbar() {
        if (progressbar == null) {
            progressbar = new JProgressBar();
            progressbar.setPreferredSize(new Dimension(1000, 22));
            progressbar.setName("progressbar");
            progressbar.setStringPainted(true);
            progressbar.setVisible(false);
        }
        return progressbar;
    }

    private JLabel getMessage() {
        if (message == null) {
            message = new JLabel();
            message.setName("message");
        }
        return message;
    }

    private void setUIState() {
        updating = true;
        assert SwingUtilities.isEventDispatchThread();
        try {
            closeButton.setEnabled(false);

        } finally {
            updating = false;
        }
    }

    private void setTextFieldValue(JFormattedTextField textField, long value) {
        if(value == Long.MAX_VALUE || value == -Long.MAX_VALUE) {
            textField.setText("");
        } else {
            textField.setValue(value);
        }
    }

    public JButton getExportButton() {
        if (exportButton == null) {
            exportButton = new JButton();
            exportButton.setToolTipText("Preview production plan");
            exportButton.setName("exportButton");
            exportButton.setText("Preview");
            exportButton.setBounds(305, 640, 72, 21);

            exportButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                }
            });
        }
        return exportButton;
    }

    private JButton getHelpButton() {
        if (helpButton == null) {
            helpButton = new JButton();
            helpButton.setBounds(470, 640, 72, 21);
            helpButton.setName("helpButton");
            helpButton.setText("Help");
            helpButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    String helpText = "This dialog is used to preview and export a production plan.<br/>" +
                            "<h1>Preview</h1>" 
                            + "After pressing 'Export', the production plan will be generated. This can take a few minutes.";

                    JEditorPane helpEditorPane = new JEditorPane("text/html", helpText); 
                    helpEditorPane.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
                    helpEditorPane.setEditable(false); 
                    JScrollPane scrollPane = new JScrollPane(helpEditorPane,
                            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);  
                    helpEditorPane.setCaretPosition(0);
                    scrollPane.setPreferredSize(new Dimension(640,445));
                    JOptionPane.showMessageDialog(helpButton, scrollPane, "Production Plan Export Dialog Help", JOptionPane.INFORMATION_MESSAGE);
                }
            });
        }
        return helpButton;
    }

    private final class EnableExport extends AbstractAction {
        @Override
        public void actionPerformed(final ActionEvent e) {
            if(isAllCheckboxSelected()) {
                getExportButton().setText("Export");
                getExportButton().setToolTipText("Export production plan");
            } else {
                getExportButton().setText("Preview");
                getExportButton().setToolTipText("Preview production plan");
            }
        }
    }

    boolean enableExport()  {
        return isAllCheckboxSelected();
    }

    boolean isAllCheckboxSelected()  {
        return false;
    }

    private final class CloseAction extends AbstractAction {
        public CloseAction() {
            super("Close");
        }

        @Override
        public void actionPerformed(final ActionEvent e) {
            close();
        }
    }

    private void close() {
        state = JOptionPane.OK_OPTION;
        setVisible(false);
        dispose();
    }
}

2 个答案:

答案 0 :(得分:1)

不能......,你能否(关于Bug的描述)进行测试

import java.awt.Cursor;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Main {

    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setSize(new Dimension(500, 500));

        final JDialog dialog = new JDialog(frame, "Production Plan Export", 
                ModalityType.MODELESS);
        dialog.setSize(300, 300);

        final JDialog dialog1 = new JDialog(dialog, "Production Plan Export", 
                ModalityType.APPLICATION_MODAL);
        dialog1.setSize(200, 200);

        frame.add(new JButton(new AbstractAction("Dialog") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                Runnable doRun = new Runnable() {

                    public void run() {
                        dialog.setVisible(true);
                        dialog1.setVisible(true);
                    }
                };
                SwingUtilities.invokeLater(doRun);
            }
        }));
        frame.setVisible(true);
    }
}

答案 1 :(得分:1)

我发现了问题。

因为我有setVisible(true)两次。一旦进入我的initGUI()方法,一次我初始化我的JDialog。

还要感谢MKorbel,我在initGUI()中移动了setAction调用,这使得按钮在使用APPLICATION_MODAL时工作