2015-05-14 5 views
5

Ich habe erwartet, dass wenn ich Alt + mnemonic verwende, der entsprechende Radioknopf fokussiert und ausgewählt wird. Meine Erwartungen basieren auf meinem Wissen darüber, wie Mnemotechniken in Swing funktionieren. Sind meine Erwartungen falsch?Wie funktioniert Mnemonik mit Optionsfeldern?

In meinem Beispielcode unten setze ich die Nummer jedes Radio-Button, um die mnemonic zu sein.

  1. "Option 1" wird ausgewählt, wenn das Programm startet.
  2. Wenn ich Alt + 3 benutze, piept das Programm bei mir, alle Mnemonics werden unterstrichen und "Option 3" wird fokussiert, aber NICHT ausgewählt. Die GUI sieht nun wie folgt aus:

http://i.stack.imgur.com/ip3om.png

  1. Wenn ich nur 2 Typ „Option 2 fokussiert wird, aber nicht ausgewählt

hier. der Code ist:

import javafx.application.Application; 
import javafx.stage.Stage; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.scene.image.*; 
import javafx.scene.input.*; 
import javafx.scene.effect.*; 
import javafx.scene.paint.*; 
import javafx.beans.value.*; 
import javafx.geometry.*; 

import javafx.event.*; 

public class RadioButtonSSCCE extends Application 
{ 
    public Parent createScene() 
    { 
     ToggleGroup group = new ToggleGroup(); 

     RadioButton rb1 = new RadioButton("Option _1"); 
     rb1.setUserData("Option 1 selected"); 
     rb1.setToggleGroup(group); 

     RadioButton rb2 = new RadioButton("Option _2"); 
     rb2.setUserData("Option 2 selected"); 
     rb2.setToggleGroup(group); 

     RadioButton rb3 = new RadioButton("Option _3"); 
     rb3.setUserData("Option 3 selected"); 
     rb3.setToggleGroup(group); 

     VBox root = new VBox(5); 
     root.setAlignment(Pos.CENTER); 
     root.getChildren().addAll(rb1, rb2, rb3); 

     ChangeListener<Toggle> cl = new ChangeListener<Toggle>() 
     { 
      @Override 
      public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) 
      { 
       if (group.getSelectedToggle() != null) 
       { 
        String text = group.getSelectedToggle().getUserData().toString(); 
        System.out.println(text); 
       } 
      } 
     }; 
     group.selectedToggleProperty().addListener(cl); 

     rb1.setSelected(true); 

     return root; 
    } 

    @Override 
    public void start(Stage primaryStage) 
    { 
     Scene scene = new Scene(createScene(), 125, 125); 
     primaryStage.setScene(scene); 
     primaryStage.setTitle("Radio Button SSCCE"); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) 
    { 
     launch(args); 
    } 
} 

ich habe, dass die mnemonic, um gefunden zu berufen ich muss:

  1. Drücken Sie die Alt-Taste und lassen Sie sie wieder los. Jetzt ist die Mnemonic jedes Radiobuttons unterstrichen.
  2. drücken Sie die Nummer und der Radiobutton wird fokussiert. Allerdings muss ich jetzt die Leertaste verwenden, um das Optionsfeld auszuwählen.

Warum muss ich die Leertaste drücken? Sollte der Radiobutton beim Drücken der Mnemonik nicht ausgewählt sein?

Warum kann ich nicht einfach Alt + Mnemonic als einzelne Tastenkombination verwenden, um einen Radiobutton auszuwählen?

Ist mein Code falsch?

Edit:

Die Aktion ist der Schlüssel das Optionsfeld auswählen. Ich habe eine generische Aktion von allen Tasten geteilt werden:

EventHandler<ActionEvent> onAction = new EventHandler<ActionEvent>() 
{ 
    @Override 
    public void handle(ActionEvent e) 
    { 
     RadioButton button = (RadioButton)e.getSource(); 
     button.setSelected(true); 
    } 
}; 

rb1.setOnAction(onAction); 
rb2.setOnAction(onAction); 
rb3.setOnAction(onAction); 

Da die Radiobuttons Teil einer Knopfgruppe ist wollte ich nicht die Möglichkeit, eine Taste zu deaktivieren.

+1

Sie sind auf die dunkle Seite gegangen, wie es scheint. ;) –

+1

Es scheint so, als würden die Mnemotechniken Aktionsereignisse auf den Optionsfeldern auslösen, aber das zwingt die Auswahl nicht wirklich dazu, sich zu ändern (ich kann nicht direkt testen, weil es auf meinem Mac als "Alt"). Das scheint jedoch nicht zu einer Änderung der Auswahl zu führen ... das könnte ein Fehler sein. –

+0

@James_D Es wirkt auf diese Weise in JavaFX 2.2 und JavaFX 8, so scheint es, die Absicht zu sein. 'CheckBox' funktioniert genauso. – OttPrime

Antwort

2

Die Mnemonic in JavaFX feuert eine ActionEvent zielgerichtet auf die registrierte Node. Im Fall von RadioButton schaltet das ActionEvent die Auswahl nicht um. Sie können dem RadioButton einen generischen Handler hinzufügen, um das ActionEvent wie folgt einzuschalten (vorausgesetzt, dass dies JavaFX 8 ist).

rb1.setOnAction(event -> rb1.setSelected(!rb1.isSelected())); 
+0

Danke. 'Im Fall von RadioButton schaltet das ActionEvent die Auswahl nicht um. - scheint mir ein" fehlendes Feature "zu sein. Wenn ich eine Mnemonik in einem 'Menü' verwende, erscheint das Menü ohne zusätzlichen Code. Auch, irgendeine Idee, warum ich zwei Schlüsselanschläge verwenden muss? 1) Drücken/Loslassen von Alt, um das mnemonische Zeichen zu unterstreichen. 2) Drücken Sie das mnemonische Zeichen, um die Aktion aufzurufen. Dies widerspricht allem, was ich bisher in einer reinen Windows-App oder einer Swing-App unter Windows gemacht habe. Warum kann ich nicht Alt + Mnemonik verwenden? Ist ein Schlüsselschlag, ohne dass mein Computer mich piept? – camickr

+0

Leider glaube ich nicht, dass dies eine großartige Lösung für Sie ist. Fortgesetzte Tests zeigen mir, dass das Klicken auf den 'RadioButton' es nicht genau auswählt. Was die mnemonische Tastenkombination betrifft, erlebe ich das nicht. Ich kann die Aktion mit Alt + 1 in einem kombinierten Schlag auslösen. Die mnemonische Unterstreichung bleibt jedoch nach dem Auslöser auf dem Bildschirm erhalten. – OttPrime

+0

Die Lösung funktionierte gut für mich. Bei meiner Aktion habe ich immer nur den Radiobutton ausgewählt und ich merke kein Problem, es ist immer ausgewählt und fokussiert. Die Aktion wird ausgelöst, wenn ich Alt + 1 benutze (und die Mnemonik bleibt unterstrichen), aber es ertönt auch ein Piepton, wenn ein Fehler gemacht wird. Wie in einer Swing-App, und Sie verwenden die Löschtaste für ein leeres JTextField (ein leeres JavaFX-TextField erzeugt dieses Geräusch nicht). Frage mich, ob es sich um ein Plattformproblem handelt. Ich verwende Windows 7. – camickr

3

Wie OttPrime in seiner Antwort stellt fest, und in dem Mnemonic Javadoc:

Wenn ein Mnemonic auf einem Scene registriert ist, und die KeyCombination erreicht die Scene unverbrauchte, dann Node das Ziel eine gesendet wird, ActionEvent.

Jetzt denke ich, diese Art von Problem ist, weil man nicht wirklich haben wollen nur ein ActionEvent an den Radioknopf gesendet, stattdessen Sie das Optionsfeld fire() möchten.

Schaltet den Status der Optionsschaltfläche nur dann um, wenn der RadioButton nicht bereits ausgewählt wurde oder nicht Teil einer ToggleGroup ist.

Hinweis: Wenn Sie eine Optionsschaltfläche auslösen, wird auch eine ActionEvent an die Schaltfläche gesendet. Hier

ist die Java 8u40 Code für Button::fire

@Override public void fire() { 
    if (!isDisabled()) { 
     fireEvent(new ActionEvent()); 
    } 
} 

Hier ist der Code für ToggleButton::fire ist

@Override public void fire() { 
    // TODO (aruiz): if (!isReadOnly(isSelected()) { 
    if (!isDisabled()) { 
     setSelected(!isSelected()); 
     fireEvent(new ActionEvent()); 
    } 
} 

Und hier ist der Code für RadioButton::fire

@Override public void fire() { 
    // we don't toggle from selected to not selected if part of a group 
    if (getToggleGroup() == null || !isSelected()) { 
     super.fire(); 
    } 
} 

Hinweis: RadioButton- ist ein ToggleButton, so ruft der Aufruf super.fire() th auf e ToggleButton fire() - Code.

Also ein Mnemonik für eine Schaltfläche wird in Ordnung sein: Alles, was die Mnemonic tut, sendet ein ActionEvent an die Schaltfläche (das ist genau das gleiche wie die Fire-Implementierung für die Schaltfläche). Allerdings ToggleButtons und Radiobuttons tun Extramaterial in ihr Feuer Methoden zur Manipulation der Auswahlzustand des ToggleButton, so mnemonic Anrufungen sind nicht tun wird.

Nun könnte man sagen, na ja, das ist OK, werde ich nur OttPrime die Problemumgehung implementieren:

rb1.setOnAction(event -> rb1.setSelected(!rb1.isSelected())); 

Dieser wird groß sein, wenn Sie die Taste über eine mnemonic auswählen, aber (soweit ich sehen kann,), wird es andere Funktionalität für die Auswahl von Schaltflächen (zum Beispiel, wenn Sie programmgesteuert das Optionsfeld auslösen und wahrscheinlich auch, wenn Sie auf das Optionsfeld mit der Maus klicken). Dies liegt daran, dass sich der Auswahlstatus der Schaltfläche zweimal ändert (einmal im fire() - Code und erneut in Ihrem Aktionscode) und Sie dies wahrscheinlich nicht möchten. Leider kann ich diese Theorie nicht wirklich testen, da ich keinen Zugriff auf eine Maschine habe, die Mnemotechniken verwenden kann.

Also, Ihre ursprüngliche Frage „Wie Mnemonics Arbeit mit Radiobuttons“ zu beantworten? => Sie nicht (zumindest in IMO, in keiner Weise, die wirklich Sinn macht).

würde ich nur disabling Mnemonic parsing für Radio-Buttons beraten und Tasten umschalten.

+0

Der Code, den ich in meiner Bearbeitung eingegeben habe, verwendet nur setSelected (true). Da ich meine Radio-Buttons in einer Gruppe verwende, möchte ich nur den Button mit dem Mnemonic auswählen. Es scheint mit diesem Ansatz zu funktionieren, oder mit der Methode fire(). Ich habe jedoch weitere Tests durchgeführt (basierend auf Ihren Kommentaren). Wenn eine Schaltfläche nicht zu einer Umschaltgruppe gehört, treten beim Starten der Maus Probleme auf. Manchmal bleibt der Button im selben Zustand und manchmal bekomme ich eine Exception. Ich stimme zu, dass es nicht so funktioniert, wie ich es erwarten würde. (+1) – camickr

+0

Wissen Sie zufällig, wie das Anklicken des Optionsfelds mit der Maus den Status der Schaltfläche ändert? Es ist nicht wichtig, ich habe gerade angefangen mit JavaFX zu spielen und bin neugierig. Ich habe versucht, die Quelle zu sehen, aber ich kann nicht sehen, wie Ereignisse behandelt werden. Wenn Sie die Klasse kennen, wäre es großartig. – camickr

+0

Ich stimme zu, dass dies die allgemeinere Lösung ist. Ich bemerkte das Problem mit dem Mausklick, nachdem ich meine Antwort gepostet hatte. – OttPrime

Verwandte Themen