2015-04-20 2 views
1

Я создал начало класса, где при нажатии клавиши со стрелкой вправо будет перемещаться прямоугольник. Но этот код работает только при добавлении setFocusable(true). Я прочитал Java Doc и многие предыдущие вопросы о переполнении стека, но я до сих пор не знаю, почему так важно setFocusable. Пожалуйста, ответьте мне, объясняя только этот код.Использование setFocusable в java

public class start extends JPanel{ 

    int x=0, xa=1; 

    public start() { 

     addKeyListener(new KeyListener(){ 

      public void keyPressed(KeyEvent ke){ 

       if(ke.getKeyCode()==KeyEvent.VK_RIGHT){ 

        xa=xa+1; 

        repaint(); 

       } 
      } 

      public void keyTyped(KeyEvent ke){} 

      public void keyReleased(KeyEvent ke){} 

     }); 

     setFocusable(true); 

    } 

    public void paint(Graphics g){ 

     super.paint(g); 

     g.fillRect(x+xa,100,40,50); 

    } 

} 
+1

Вместо «KeyListener» используйте [привязки клавиш] (https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html#howto) –

+0

Спасибо за предложение, но все же я спрашиваю о setFocusable – user3423267

ответ

0

focusable флаг указывает, может ли компонент получить фокус или нет. Компонент JPanel является настраиваемым по умолчанию, поэтому при его настройке на true изменений не будет. Также setFocusable не устанавливает фокус сам по себе.

+0

Вот что я прошу. Когда я пытаюсь переместить блок прямоугольника без включенного setFocusable (true), он не показывает проверку ... Я имею в виду, что этот код не работает без 'setFocusable (true)' – user3423267

0

Когда кадр/окно отображается по умолчанию Компонент FocusTraversalPolicy по умолчанию задается фокус. DefaultFocusTraversalPolicy аккомпанирует компонент, если он является фокусным, и isFocusTraversableOverridden является истинным, или если его peer является сфокусированным.

Когда setFocusable(true) называется, флаг isFocusTraversableOverridden установлен в FOCUS_TRAVERSABLE_SET, так что это избирает component быть выбран DefaultFocusTraversalPolicy в качестве компонента по умолчанию. Таким образом, даже если JPanel по умолчанию сконфигурирован, явный вызов делает его выбранным в качестве компонента по умолчанию для получения фокуса.

В любом случае, это неправильный способ запроситьфокус на Component. Вы должны попробовать requestFocus или requestFocusInWindow после того, как Component сделана видимой.

Кроме того, рассмотрите возможность переопределения paintComponent вместо paint.

+0

Можете ли вы быть менее технический? – user3423267

+0

Когда отображается кадр, он полагается на политику, чтобы сосредоточиться на компоненте по умолчанию. По умолчанию эта политика выбирает первый компонент, который является фокусным, а isFocusTraversableOverridden - true. Когда вы вызываете setFocusable(), isFocusTraversableOverridden имеет значение true, поэтому это позволяет компоненту получить фокус после отображения кадра. Просто помните, что это не способ установить фокус на компонент. Dunno, если его все яснее, надеюсь. – Renatols

+0

Обратите также внимание на javadoc http://docs.oracle.com/javase/7/docs/api/java/awt/DefaultFocusTraversalPolicy.html – Renatols

1

но я до сих пор не знаю, почему setFocusable так важен.

События отправляются только на компонент, имеющий фокус. Таким образом, ваш KeyEvent будет отправлен на панель только в том случае, если он «сфокусирован» и имеет фокус.

См. Motion Using the Keyboard для получения дополнительной информации по этой теме, включая два разных решения.

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