2016-05-05 2 views
0

У меня есть подкласс JDialog ... переопределенный SetVisible метод выглядит следующим образом:Put внимание на JTextField в JDialog, когда последний сделал видимыми

public void setVisible(boolean visible){ 
    super.setVisible(visible); 

    if(visible){ 
     inputJTF.requestFocus(); 
    } 
} 

На самом деле, когда я отобразить JDialog фокус является на JTF ... но последнее также является «первым» компонентом (панель NORTH) в JDialog, так что это не удивительно.

Но мой код тестирования рассказывающий мне другие вещи:

EventQueue.invokeAndWait(new Runnable() { 
     @Override 
     public void run() { 
      app.mainFrame.searchDlg.setVisible(true); 

      // all 3 of these asserts fail... 
      assertTrue(app.mainFrame.searchDlg.inputJTF.hasFocus()); 
      Component focusOwner = app.mainFrame.searchDlg.getFocusOwner(); 
      assertFalse(focusOwner == null); 
      assertTrue(String.format("# focus owner %s", focusOwner.getClass()), focusOwner == app.mainFrame.searchDlg.inputJTF); 

     } 
    }); 

... так ведь я получаю сказали, что «владелец фокус» является недействительным ... и JTF не имеет фокуса. Может ли кто-нибудь объяснить, что происходит?

ответ

0

Ага ... это, оказывается, является одним из тех вещей «Gotcha» с JUnit и Java GUI.

тест в моем коде не может ... но следующий код не:

EventQueue.invokeAndWait(new Runnable() { 
     @Override 
     public void run() { 
      searchDlg.setVisible(true); 
      assertTrue(searchDlg.queryString == null); 
     } 
    }); 
    Robot robot = new Robot(); 
    robot.delay(10); 
    EventQueue.invokeAndWait(new Runnable() { 
     @Override 
     public void run() { 
      // now passes 
      assertTrue(app.mainFrame.searchDlg.inputJTF.hasFocus()); 
     } 
    }); 

... если robot.delay() сводится к 1, или отсутствует, то неудача случается.

Очевидно, что это связано с конечным временем, необходимым для реализации JDialog.

Ответ Роба Камика интересен, и RequestFocusListener работает по назначению.

Однако его ответ фактически не отвечает на вопрос: что было: что происходит, и почему этот тест терпит неудачу?

3

Большинство диалогов являются модальными, что означает, что инструкция после оператора setVisible (true) не выполняется до тех пор, пока диалог не будет закрыт.

По умолчанию фокус переходит к первому компоненту в диалоговом окне.

Если по какой-то причине вам нужно сосредоточиться на другом компоненте, тогда проверьте Dialog Focus на решение, позволяющее вам контролировать, какой компонент получить фокус.

Это решение использует AncestorListener, чтобы сосредоточиться на компоненте, когда компонент отображается в видимом диалоговом окне/кадре.

+0

"заявление после инструкции setVisible (true) не выполняется до закрытия диалогового окна" ... ОК ... многое объясняет, спасибо. Вы случайно поняли, почему 'getFocusOwner()' возвратит 'null'? Теперь, проверяя свой диалог ... –

+0

также, если я могу ... Я знаком с setVisible (true), блокирующим поток (даже EDT) ... и потратил много времени, царапая себе голову над ним (новый «Дисковые насосы» и т. Д.). Но почему во втором фрагменте кода он не блокирует поток THAT EDT? –

+1

'Но почему, во втором фрагменте кода,' - Какую именно проблему вы пытаетесь решить? Почему вам все равно, что сфокусировано? FYI, вы не всегда можете предположить, что весь код выполняется последовательно. Точно так же вы используете invokeAndWait (...), другой код может использовать invokeLater(), что означает, что фокус не может быть определен, когда выполняются ваши инструкции assert. Опубликуйте надлежащий 'SSCCE', который демонстрирует проблему. Фрагменты кода не помогают, поскольку мы не понимаем контекста использования кода. – camickr