Свойство JDialog изменило поведение

1

Я реализовал JDialog, который соответствует строчке верхнего ответа, рассмотренного в этом предыдущем вопросе. Код полностью работает независимо от того, что при наличии недопустимого ввода два PropertyChangedEvents возникают, когда требуется только одно. Это привело к формулировке SSCCE ниже:

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;

public class Test{  
    public Test(){
        JOptionPane optionPane = new JOptionPane(null, JOptionPane.OK_CANCEL_OPTION);

        final JDialog dialog = new JDialog(new JFrame(), "Test", true);
        dialog.setContentPane(optionPane);

        optionPane.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent e) {
                String prop = e.getPropertyName();

                if (dialog.isVisible() && (e.getSource() == optionPane) && (JOptionPane.VALUE_PROPERTY.equals(prop))){
                    java.lang.System.out.println("Code Reached");
                    optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);
                }
            }
        });
        dialog.pack();
        dialog.setVisible(true);
    }

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

Из этого SSCCE можно сказать, что второй и нежелательный PropertyChangedEvent вызван линией кода optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE); этот код, однако, необходим для предотвращения блокировки окна после недопустимых входов. Есть ли способ запретить JOptionPane.setValue() вызвать PropertyChangedEvent или определить, когда PropertyChangedEvent был вызван сбросом значения JOptionPane и предотвращением возникновения if? Благодарю.

Теги:
swing
joptionpane
jdialog

1 ответ

1
Лучший ответ

Если вам удастся отключить прослушиватель событий, вы можете сделать это:

A) установить (логический) флаг в объекте PropertyChangeListener

или

B) удалить eventlistener из опцииPane:

final PropertyChangeListener pcl = new PropertyChangeListener() {
    public void propertyChange(PropertyChangeEvent e) {
        String prop = e.getPropertyName();

        if (dialog.isVisible() && (e.getSource() == optionPane) && (JOptionPane.VALUE_PROPERTY.equals(prop))){
            java.lang.System.out.println("Code Reached");
            optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);

            optionPane.removePropertyChangeListener(pcl);
        }
    }
}
optionPane.addPropertyChangeListener(pcl);

Однако это зависит от цели диалога. Если вы закроете диалоговое окно, то вариант B хорош.

РЕДАКТИРОВАТЬ:

Второе событие вызвано optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE), поэтому, если вы проверите это значение, оно может работать.

if (dialog.isVisible() 
        && e.getSource() == optionPane 
        && JOptionPane.VALUE_PROPERTY.equals(prop)
        && !optionPane.getValue().equals(JOptionPane.UNINITIALIZED_VALUE)){

    java.lang.System.out.println("Code Reached");
    optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);
}
  • 0
    В настоящее время я использую обходной путь, похожий на A, посредством которого я переключаю логическое значение; это, однако, кажется немного хитрым решением. К сожалению, я не могу просто удалить слушателя, так как я хочу, чтобы JDialog оставался на экране и активировался до тех пор, пока не будет предоставлен действительный ввод (или, в случае предоставленного SSCCE, он должен оставаться неопределенно долго).
  • 0
    Редактирование идеально, я не могу поверить, что я не видел это!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню