2012-04-17 5 views
3

Я хочу, чтобы мой графический интерфейс выполнял некоторые проверки при появлении JOptionPane. Потому что я не могу найти другого способа, хотя я могу делать это каждый раз, когда окно приложения теряет фокус (просто проверяя строку). По этой причине я добавил следующий код на своем JFrame:WindowListener не работает должным образом

appFrame.addWindowListener(new WindowAdapter() { 

      @Override 
      public void windowLostFocus(WindowEvent e) { 
       System.out.println("Focus Lost"); 

      } 
      @Override 
      public void windowClosing(WindowEvent e) { 
       //some other stuff here that work 
      } 
}); 

Завершающий прослушивание окна работает отлично. Хотя, когда JFrame не фокусируется, ничего не происходит. Не следует ли печатать «Focus Lost» каждый раз, когда я переключаюсь с JFrame на другое окно? Кроме того, будет ли этот метод запущен, когда будет показана JOptionPane?

+0

Это кажется обратным способом сделать это. Что вызывает отображение опций? Почему бы не вызвать этот код в этом триггере? –

+0

JOptionPane отображается, когда дублирование строк находится в какой-либо другой части приложения (не имеет ничего общего с графическим интерфейсом). Из этой строки JOptionPane строка изменяется, и это изменение должно быть отражено в заголовке JFrame. Поскольку эти классы не сообщают, хотя слушатель окна был бы простым способом проверить это изменение. – Giannis

+0

Возможно, здесь будет полезно указать ОС ... Я не уверен, что Windows отправит сообщение в окно, чтобы сообщить, что он больше не активен (или если JVM обрабатывает его) – SJuan76

ответ

4

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

WindowAdapter удобный класс, так что вы можете создать прослушиватель и зарегистрировать его для нескольких типов событий.Вы только зарегистрировали для одного набора событий, необходимо также зарегистрировать его для событий фокуса с помощью: Window.addWindowFocusListener()

WindowAdapter adapter = new WindowAdapter() { 
     @Override 
     public void windowLostFocus(WindowEvent e) { 
      System.out.println("Focus Lost"); 
     } 
     @Override 
     public void windowClosing(WindowEvent e) { 
      //some other stuff here that work 
     } 
    }; 
appFrame.addWindowListener(adapter); 
appFrame.addWindowFocusListener(adapter); 
+0

Закончено делать что-то похожее на наблюдателя, но это отвечает на мой вопрос :) – Giannis

6

Ключом ко мне является то, что вы хотите изменить графический интерфейс, вызванный изменением переменной String. Лучший способ решить эту задачу - сделать переменную String связанной структурой с помощью PropertyChangeListenerSupport. Таким образом, вы можете подключить GUI к PropertyChangeListener классу, который содержит переменную String, а затем будет уведомлен, когда он изменится, что позволит вам соответствующим образом обновить графический интерфейс.

Если вы идете по этому маршруту, подумайте о том, чтобы дать наблюдаемому классу поле SwingPropertyChangeSupport, чтобы слушатели были уведомлены о потоке событий Swing и, надеюсь, избегали любых проблем параллелизма Swing.

Вот краткий пример:

import java.awt.Dimension; 
import java.awt.event.*; 
import java.beans.*; 
import javax.swing.*; 
import javax.swing.event.SwingPropertyChangeSupport; 

public class ShowPropertyChangeSupport { 
    @SuppressWarnings("serial") 
    private static void createAndShowGui() { 
     final MainGUI mainGui = new MainGUI("Title"); 
     final ObservedClass observedClass = new ObservedClass(); 
     observedClass.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent pcEvt) { 
      if (pcEvt.getPropertyName().equals(ObservedClass.BOUND_PROPERTY)) { 
       mainGui.setTitle(pcEvt.getNewValue().toString()); 
      } 
     } 
     }); 

     mainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainGui.pack(); 
     mainGui.setLocationRelativeTo(null); 
     mainGui.setVisible(true); 

     int timerDelay = 6000; // every 6 seconds 
     new Timer(timerDelay, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      String result = JOptionPane.showInputDialog(mainGui, 
        "Please enter a String", "Set GUI title", JOptionPane.PLAIN_MESSAGE); 
      if (result != null) { 
       observedClass.setBoundProperty(result); 
      } 
     } 
     }){{setInitialDelay(1000);}}.start(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

// ** note that I don't like extending JFrame, 
// but will do this for sake of example simplicity 
class MainGUI extends JFrame { 
    public MainGUI(String title) { 
     super(title); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(400, 300); 
    } 

} 

class ObservedClass { 
    public static final String BOUND_PROPERTY = "bound property"; 
    private String boundProperty = ""; 
    private SwingPropertyChangeSupport spcSupport = new SwingPropertyChangeSupport(
     this); 

    public SwingPropertyChangeSupport getSpcSupport() { 
     return spcSupport; 
    } 

    public void setSpcSupport(SwingPropertyChangeSupport spcSupport) { 
     this.spcSupport = spcSupport; 
    } 

    public String getBoundProperty() { 
     return boundProperty; 
    } 

    public void setBoundProperty(String boundProperty) { 
     String oldValue = this.boundProperty; 
     String newValue = boundProperty; 
     this.boundProperty = newValue; 
     spcSupport.firePropertyChange(BOUND_PROPERTY, oldValue, newValue); 
    } 

    public void addPropertyChangeListener(PropertyChangeListener listener) { 
     spcSupport.addPropertyChangeListener(listener); 
    } 

    public void removePropertyChangeListener(PropertyChangeListener listener) { 
     spcSupport.removePropertyChangeListener(listener); 
    } 

} 

Ключ ко всему этому, на мой взгляд, чтобы использовать слушателя так, что класс с оценкой собственности - строка прослушивается - не имеет никакого знания GUI, слушатель и графический интерфейс, также не имеет знания о классе со связанным свойством. Они полностью развязаны.

+1

Да или, вообще говоря, приложение нуждается в собственной очереди событий - это глобальное место для регистрации слушателей и событий отправки. Есть много способов получить это, не знаю, распространена ли какая-либо конкретная. –

+0

Большое спасибо за этот кусок кода, это действительно интересно. В итоге я сделал что-то похожее на шаблон наблюдателя. Я уверен, что мне это понадобится в будущем. – Giannis

+0

@ Giannis: вот и все это - шаблон наблюдателя, но с небольшим дополнительным оформлением окон, и поэтому вы в основном делаете то, что я предлагаю. Удачи с вашим проектом! –

2

1) JOptionPane/модальный JDialog получил модальность вопроса, но модальность может быть преимуществом, если все контейнеры получили собственный хозяин, для реального решения проблемы вы должны знать (я говорю о том, как я могу сделать тест, что)

2) Пожалуйста, с должным уважением, я не знаю, почему вам нужно, что, почему причинам мне нужно знать о том, что есть о бизнес-правил, вы всегда должны знать ...., и если это делается на EDT

Смежные вопросы