2015-09-04 36 views
0

嗨那裏我正在開發一個Java應用程序(在Mac中)。當用戶按下箭頭時,我想讓它做點什麼。當按下箭頭鍵綁定沒有響應

我的代碼如下:

public class Main { 

static JScrollPane scrollPane; 

public static void main(String[] args) { 


    JFrame f = new JFrame(); 
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 
    f.setBounds(0, 0, dim.width, dim.height); 

    StandartPanel p = new StandartPanel(); 

    f.add(p); 

    JToolBar tb = new JToolBar(); 

    tb.add(new JButton("button")); 

    f.add(tb); 
    f.setVisible(true); 
} 

}

它簡單地創建一個JFrame,並在其中一個StandartPanel並且具有按鈕JToolBar中提出的程序。

的StandartPanel的代碼如下:

public class StandartPanel extends JPanel { 


public StandartPanel() { 

    for(int i = 0; i < 10; i++) 
     this.add(new JLabel("Jlabel number: " + i)); 

    this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "forward"); 
    this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "forward"); 
    this.getActionMap().put("forward", new AbstractAction() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("pressed"); 
     } 
    }); 
} 

}

for循環是並不重要,重要的是它打印「按下」按下d或向下時。

當我實際按D鍵時會打印「按下」,但是當我點擊它時什麼也不做。

在嘗試了一些事情後,我發現如果不是向JToolBar添加JButton,而是添加JLabel,它會起作用(如果我不添加任何東西,它也可以)。

因此,向JToolBar添加JButton會以某種方式停止使用向下按鈕的鍵綁定。

任何想法,爲什麼會發生以及如何修復?

謝謝!

+0

Hava看看[this](http://stackoverflow.com/a/17049479/4857909) –

+0

看看http://stackoverflow.com/questions/9973190/keyadapter-listener-works-in-windows-not-on-mac –

+0

@GeorgiPenev它也不適用於我(Windows)。他也已經使用KeyBindings,而不是KeyListener。 –

回答

1

最簡單的方法是設置您的( JToolBar和 )JButton不可聚焦。 (請參閱this,JToolBar通常會註冊向上/向下/向左/向右以切換工具欄內按鈕的焦點。)但要小心!這將阻止JToolbar從一個項目跳轉到另一個項目。 (如果您想保留該功能,看看MadProgrammer的回答) - 實現在你的代碼會是這樣的:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 

import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JToolBar; 
import javax.swing.KeyStroke; 

public class Main { 

    static JScrollPane scrollPane; 

    public static void main(String[] args) { 

     JFrame f = new JFrame(); 
     Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 
     f.setBounds(0, 0, dim.width, dim.height); 

     StandartPanel p = new StandartPanel(); 

     f.add(p); 

     JToolBar tb = new JToolBar(); 

     JButton button = new JButton("Button"); 
     button.setFocusable(false); 

     tb.add(button); 
     //tb.setFocusable(false); 

     f.add(tb, BorderLayout.NORTH); 
     f.setVisible(true); 
    } 

    static class StandartPanel extends JPanel { 

     public StandartPanel() { 

      for (int i = 0; i < 10; i++) { 
       this.add(new JLabel("Jlabel number: " + i)); 
      } 

      this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
        KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "forward"); 
      this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
        KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "forward"); 
      this.getActionMap().put("forward", new AbstractAction() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("pressed"); 
       } 
      }); 
     } 

    } 

} 
+0

使用WHEN_IN_FOCUSED_WINDOW表示只要組件位於當前聚焦的窗口內,鍵綁定應該觸發。鑑於OP可以讓它爲[D]鍵工作,但向下[向下箭頭],暗示它們還有其他作用 – MadProgrammer

+0

@MadProgrammer JToolBar自動註冊UP/DOWN/LEFT/RIGHT的動作一個項目到另一個項目) - 設置所有按鈕不可聚焦將防止這種情況。 (這就是爲什麼它可以與JLabels協同工作的原因) –

+0

它不應該(但確實)有所作爲,但是正在改變用戶對工具欄的期望值得讓鍵綁定工作。有趣的事情要考慮;) – MadProgrammer

1

測試它在我的Mac:

this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "forward"); 

沒有工作,但是,由於某種原因,我無法解釋,使用...

this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "forward"); 

確實

哦,還有,而非美國。荷蘭國際集團......

Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 
f.setBounds(0, 0, dim.width, dim.height); 

考慮使用...

f.setExtendedState(JFrame.MAXIMIZED_BOTH); 

它不會只給一個simular結果,它會考慮到的東西像隱藏/顯示碼頭和代表的方式窗口狀態這是更正確的,它的狀態(即,最大化,而不是隻是「填充」該區域)

+0

(+1)我的猜測**你的解決方案的工作原理是因爲它只在鍵被釋放時觸發事件,JToolBar可能在鍵上按下。 (並阻止其他行爲) - 但我確定我的「理論」可以很容易被駁回:P –

+0

@LuxxMiner我認爲,但'JToolBar'也具有'KeyEvent.VK_KP_DOWN'的綁定,我也可以使用,沒有修改就好,似乎有更多的事情發生在'VK_DOWN'鍵上,我沒有看到。如果我在OP的「StandartPanel」中添加一個可調焦的組件,並將其聚焦,那麼這一切都可以正常工作......我在這個階段難住,因爲WHEN_IN_FOCUSED_WINDOW不應該關心還有誰可能響應關鍵事件從我的經驗到現在) – MadProgrammer

+0

@MadProgrammer謝謝!我試了一下,它的工作! – Antonio