JMenuItem und Accelerator

Status
Nicht offen für weitere Antworten.
G

Gast2

Gast
Hallo zusammen,

kann man ein Accelerator immer verfügbar machen, auch wenn ein JDialog usw. gerade den Focus hat?

[HIGHLIGHT="Java"]
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class TestMenue extends JFrame {

JMenuBar menuBar;

public TestMenue() {
menuBar = new JMenuBar();

JMenu test = new JMenu("test");

JMenuItem oeffnen = new JMenuItem("Öffnen");
oeffnen.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
JDialog dialog = new JDialog();
dialog.setSize(100, 100);
dialog.setVisible(true);
}

});
JMenuItem save = new JMenuItem("Save");
save.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
System.out.println("Save soll immer funktionieren");

}

});
save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
test.add(oeffnen);
test.add(save);
menuBar.add(test);
setJMenuBar(menuBar);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);

}

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

public void run() {
new TestMenue().setVisible(true);

}

});

}

}


[/HIGHLIGHT]

Also wenn man auf öffnen klickt dann funktioniert STRG + S nicht mehr wie kann man das ändern? Nur über die InputMap??
 
Zuletzt bearbeitet von einem Moderator:

Ebenius

Top Contributor
Ich glaub, das kann man gar nicht einfach so ändern. Die Accelerators hängen in der WHEN_IN_FOCUSED_WINDOW-InputMap. Wenn ein anderes Fenster den Fokus hat, dann greifen diese key mappings natürlich nicht.

Ebenius
 
G

Gast2

Gast
jop hab ich auch gemerkt...
Es gibt 2 Möglichkeiten den JDialog usw. den frame als owner mitgeben
oder
[HIGHLIGHT="Java"]

KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor(){

@Override
public boolean postProcessKeyEvent(KeyEvent e) {
// TODO Auto-generated method stub
return false;
}

});
[/HIGHLIGHT]
 
G

Gast2

Gast
okay ich hab es nochmal versucht auch wenn der JDialog einen owner hat funktioniert es nicht man muss noch einen JButton reinsetzen...
Wie könnte man das Problem umgehen(außer variante 2 )... Kennt noch jemand eine Möglichkeit
[HIGHLIGHT="Java"]
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class TestMenue extends JFrame {

JMenuBar menuBar;

public TestMenue() {
menuBar = new JMenuBar();

JMenu test = new JMenu("test");

JMenuItem oeffnen = new JMenuItem("Öffnen");
oeffnen.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
JDialog dialog = new JDialog(TestMenue .this);
dialog .add(newJButton());
dialog.setSize(100, 100);
dialog.setVisible(true);
}

});
JMenuItem save = new JMenuItem("Save");
save.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
System.out.println("Save soll immer funktionieren");

}

});
save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
test.add(oeffnen);
test.add(save);
menuBar.add(test);
setJMenuBar(menuBar);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);

}

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

public void run() {
new TestMenue().setVisible(true);

}

});

}

}

[/HIGHLIGHT]
 

Ebenius

Top Contributor
Du brauchst nen Fokus in dem Dialog. Wenn keine Komponente den Fokus bekommen kann, wird's schwer. Vielleicht geht "dialog.setFocusable(true);" statt des JButtons.

Viel Erfolg!
Ebenius
 
G

Gast2

Gast
nee ich hab mich glaub falsch ausgedrückt...
Ich dachte wenn man einem jDialog einen owner mitgibt dann funktionieren die KeyEvent im Menü noch, aber sobald der JDialog einen Komponente enthält funktionieren sie nicht mehr--> das ist mir aufgefallen.
Meine Frage war ob es vielleicht eine andere Möglichkeit wie
[HIGHLIGHT="Java"]
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor() {

public boolean postProcessKeyEvent(KeyEvent e) {

if (e.isControlDown() && KeyStroke.getKeyStrokeForEvent(e).equals(menuItem.getAccelerator())) {
actionListener.actionPerformed(new ActionEvent(menuItem, e.getID(), "KeyEvent.KEY_TYPED"));
}
return false;
}
});

[/HIGHLIGHT]
wie sowas hier gibt? das funktioniert auf jeden Fall weiß aber nicht ob es sehr performant ist =)...
 

Ebenius

Top Contributor
Probier mal, ob sowas geht: [HIGHLIGHT=Java]final KeyboardFocusManager fm =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
fm.addKeyEventPostProcessor(new KeyEventPostProcessor() {

public boolean postProcessKeyEvent(KeyEvent e) {
if (fm.getActiveWindow() != mainFrame
&& !e.isConsumed()
&& isValidKeyEventForKeyBindings(e)) {
SwingUtilities.processKeyBindings(new KeyEvent(mainFrame
.getRootPane(), e.getID(), e.getWhen(), e.getModifiersEx(), e
.getKeyCode(), e.getKeyChar(), e.getKeyLocation()));
}
return false;
}

// copied from SwingUtitilities (invisible)
private boolean isValidKeyEventForKeyBindings(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_TYPED) {
int mod = e.getModifiers();
if (((mod & ActionEvent.ALT_MASK) != 0)
&& ((mod & ActionEvent.CTRL_MASK) == 0)) {
// filter out typed "alt-?" keys, but not those created
// with AltGr, and not control characters
return false;
}
}
return true;
}
});[/HIGHLIGHT]

Ebenius
 

Ebenius

Top Contributor
als

Stimmt. Aber Performance spielt hier keine Rolle. Wieviele Tastenanschläge möchtest Du denn pro Millisekunde verabeiten? Meine Lösung schlägt einfach eine Brücke zu allen WHEN_IN_FOCUSED_WINDOW-KeyBindings. Wenn Du das nur für eine einzige Aktion benötigst, dann sind beide Ansätze natürlich übertrieben.

Ebenius

Ebenius
 
G

Gast2

Gast
Ja aber was an deiner besser ist, es werden die Tastenschläge(Shortcuts) dann auf jeden Fall nur einmal ausgeführt...
Nee ist geplant für alle shortcuts, die in einem JMenu vorkommen...
 
G

Gast2

Gast
[HIGHLIGHT="Java"]
KeyStroke.getKeyStrokeForEvent(e).equals(menuItem.getAccelerator()
[/HIGHLIGHT]

die Zeile muss noch mit rein sonst führt er es bei jedem Tastenschlag aus und führt die aktion gefühlte 100 mal aus ;)
 

Ebenius

Top Contributor
[HIGHLIGHT="Java"]
KeyStroke.getKeyStrokeForEvent(e).equals(menuItem.getAccelerator()
[/HIGHLIGHT]

die Zeile muss noch mit rein sonst führt er es bei jedem Tastenschlag aus und führt die aktion gefühlte 100 mal aus ;)
Es war von mir beabsichtigt, alle in Frage kommenden KeyBindings an das mainFrame weiterzuleiten. Performance ist dabei kein Thema.

Ebenius
 
G

Gast2

Gast
Ja du hast alle weitergeleitet, was im Prinzip auch okay ist, aber diese werden nicht nur einmal weitergeleitet sondern mehrmals

Sagen wir z.B. du hast einen shortcut STRG + G um irgendwas zu zoomen...
Dann wird dieser merhmals ausgeführt und die zoom methode wird mehrmals ausgeführt...
Das heißt es wird nicht ein zoom step ausgeführt sondern mehrere auf einmal
 

Ebenius

Top Contributor
Ja du hast alle weitergeleitet, was im Prinzip auch okay ist, aber diese werden nicht nur einmal weitergeleitet sondern mehrmals
Nö. Da musst Du was anderes falsch machen. Hier ein bisschen Schweine-Code zum Testen für Dich: [HIGHLIGHT="Java"]public static void main(String[] args) {
final JTextPane textPane = new JTextPane();
textPane.setPreferredSize(new Dimension(400, 400));

final JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new AbstractAction("Open Dialog") {

{
putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_O));
}

public void actionPerformed(ActionEvent e) {
final JComponent c = (JComponent) e.getSource();
final JFrame mainFrame = (JFrame) SwingUtilities.getWindowAncestor(c);
final JDialog dialog = new JDialog(mainFrame, "Child Dialog");
final JLabel label =
new JLabel("Try the main frame's menu action accelerator here");
final JPanel dialogPane = new JPanel(new GridLayout(2, 1, 6, 6));
dialogPane.add(label);
dialogPane.add(new JButton(new AbstractAction("Close") {

public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
}));
dialog.setContentPane(dialogPane);
dialog.setModal(true);
dialog.pack();
dialog.setResizable(false);
dialog.setLocationRelativeTo(mainFrame);

final KeyboardFocusManager fm =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
final KeyEventPostProcessor keyEventPostProcessor =
new KeyEventPostProcessor() {

public boolean postProcessKeyEvent(KeyEvent e) {
if (fm.getActiveWindow() != mainFrame
&& !e.isConsumed()
&& isValidKeyEventForKeyBindings(e)) {
SwingUtilities.processKeyBindings(new KeyEvent(mainFrame
.getRootPane(), e.getID(), e.getWhen(), e
.getModifiersEx(), e.getKeyCode(), e.getKeyChar(),
e.getKeyLocation()));
}

return false;
}

// copied from SwingUtitilities (invisible)
private boolean isValidKeyEventForKeyBindings(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_TYPED) {
int mod = e.getModifiers();
if (((mod & ActionEvent.ALT_MASK) != 0)
&& ((mod & ActionEvent.CTRL_MASK) == 0)) {
// filter out typed "alt-?" keys, but not those created
// with AltGr, and not control characters
return false;
}
}
return true;
}
};

try {
fm.addKeyEventPostProcessor(keyEventPostProcessor);
dialog.setVisible(true);
} finally {
fm.removeKeyEventPostProcessor(keyEventPostProcessor);
}
}
}), BorderLayout.PAGE_END);

final JPanel panel = new JPanel(new BorderLayout(6, 6));
panel.add(buttonPanel, BorderLayout.LINE_END);
panel.add(new JScrollPane(textPane), BorderLayout.CENTER);

final JMenuBar menuBar = new JMenuBar();
final JMenu menu = new JMenu("Menu");
menu.setMnemonic(KeyEvent.VK_M);
menu.add(new AbstractAction("Add some Text") {

{
putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_A));
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
InputEvent.CTRL_DOWN_MASK));
}

public void actionPerformed(ActionEvent e) {
final Document doc = textPane.getDocument();
try {
doc.insertString(doc.getLength(), new Date()
+ " Action performed\n", null);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
});
menuBar.add(menu);

final JFrame mainFrame = new JFrame("KeyBinding Fun");
mainFrame.setJMenuBar(menuBar);
mainFrame.setContentPane(panel);
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}[/HIGHLIGHT]

Ebenius
 
G

Gast2

Gast
ahhhhhhhhhhhhhhhhh =)... ich hab dem KeyManager zuviele gleiche KeyEventPostProcessor hinzugefügt, darum hat er es zu oft ausgeführt *omg*...
danke hast mich auf den richtigen weg gebracht :D...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Accelerator zu JMenuItem des JPopupMenu einer JList AWT, Swing, JavaFX & SWT 2
coolian ActionListener funktonirt nicht richtig auf JMenuItem AWT, Swing, JavaFX & SWT 4
J Swing JMenuItem blockiert JMenuBar AWT, Swing, JavaFX & SWT 2
F JMenuItem mit KeyStroke kombinieren AWT, Swing, JavaFX & SWT 1
javampir Look&Feel von JMenuItem AWT, Swing, JavaFX & SWT 3
M JMenuBar, JMenu, JMenuItem wird nicht angezeigt AWT, Swing, JavaFX & SWT 16
K JMenuItem-Shortcut WENN Menüleiste verborgen ist AWT, Swing, JavaFX & SWT 4
J Swing JMenuItem-Event?? AWT, Swing, JavaFX & SWT 3
J Swing JMenuItem auf setEnabled(false) setzen? AWT, Swing, JavaFX & SWT 3
B JMenuItem Anzeigeproblem AWT, Swing, JavaFX & SWT 6
E Swing JTextField als JMenuItem AWT, Swing, JavaFX & SWT 3
G PopupMenu für ein JmenuItem AWT, Swing, JavaFX & SWT 3
N Swing Nimbus arbeitet nicht korrekt korrekt bei setEnabled() für JMenuItem AWT, Swing, JavaFX & SWT 2
F JMenuItem exit AWT, Swing, JavaFX & SWT 2
M Swing JMenuItem und der ActionListener AWT, Swing, JavaFX & SWT 2
S Probleme mit JMenu und JMenuItem AWT, Swing, JavaFX & SWT 2
sylo Position des Icons bei JMenuItem AWT, Swing, JavaFX & SWT 11
Semox Swing JMenuItem-Auswahl mit Aktion ausführen AWT, Swing, JavaFX & SWT 4
pinerski Probleme mit JPopupMenu und JMenuItem AWT, Swing, JavaFX & SWT 7
T Problem mit KeyStroke auf JMenuItem (1.4.2 <-> 6) AWT, Swing, JavaFX & SWT 3
T Von JMenuItem setText auf JButton AWT, Swing, JavaFX & SWT 2
ModellbahnerTT JMenuItem AWT, Swing, JavaFX & SWT 5
O Verstehe ActionListener in Verbindung mit JMenuItem AWT, Swing, JavaFX & SWT 4
Iron Monkey JPopupMenu/JMenuItem Index für getSubElements()[] ermitteln AWT, Swing, JavaFX & SWT 8
0 JMenuItem nicht in zwei JMenus möglich? AWT, Swing, JavaFX & SWT 2
G JMenuItem & AbstractAction = Problem? AWT, Swing, JavaFX & SWT 2
G identische JMenuItem im actionListener unterscheiden AWT, Swing, JavaFX & SWT 4
F ID zu JMenuItem AWT, Swing, JavaFX & SWT 7
A Bei Klick auf disabled JMenuItem JMenu nicht schließen AWT, Swing, JavaFX & SWT 2
Z JMenuItem AWT, Swing, JavaFX & SWT 2
C JMenuItem ActionListener AWT, Swing, JavaFX & SWT 26
DeeDee0815 F-Taste auf JMenuItem legen AWT, Swing, JavaFX & SWT 2
padde479 JMenuItem mit Image AWT, Swing, JavaFX & SWT 2
P JMenu / JMenuItem durch Rekursion Icons entfernen AWT, Swing, JavaFX & SWT 4
S java.lang.verifyError beim Casten nach JMenuItem AWT, Swing, JavaFX & SWT 13
B ActionListener JMenuItem AWT, Swing, JavaFX & SWT 2
B JMenuItem AWT, Swing, JavaFX & SWT 2
S Öffnen eines JDialog über JMenuItem / Fenster zu viel. AWT, Swing, JavaFX & SWT 2
T JMenu/JMenuItem Component auf der geaddet wurde AWT, Swing, JavaFX & SWT 16
G JMenu About ohne JMenuItem AWT, Swing, JavaFX & SWT 11
G Freiraum bei JMenuItem mit Icon AWT, Swing, JavaFX & SWT 4
B ActionListener/JMenuItem/getSource() . AWT, Swing, JavaFX & SWT 5
F Darstellung von Tastaturkürzel in JMenuItem AWT, Swing, JavaFX & SWT 13
Z JMenu und JMenuItem: MouseOver-Farbe ändern AWT, Swing, JavaFX & SWT 9
J JMenuItem und ActionListener AWT, Swing, JavaFX & SWT 3
B Häkchen bei JMenuItem? AWT, Swing, JavaFX & SWT 6
B Alle jMenu und JMenuItem in einem Array AWT, Swing, JavaFX & SWT 4
W Accelerator oder KeyListener AWT, Swing, JavaFX & SWT 3
D JMenu -> Accelerator AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben