2015-01-16 13 views
5

Ich habe eine Frage über die Verwendung von virtuellen Tastatur auf Touch unterstützt PC mit Windows 8.1. Ich habe es geschafft, die virtuelle Tastatur zu zeigen, wenn Textfeld mit Java-Schalter fokussiert ist:JavaFX virtuelle Tastatur überlappt Knoten

-Dcom.sun.javafx.isEmbedded=true -Dcom.sun.javafx.virtualKeyboard=javafx 

Ich fand, wie man das auf JavaFX Virtual Keyboard doesn't show1.

Aber wenn die Tastatur angezeigt wird, überlagert es Knoten unter der Tastatur.

Nach was ich gelesen habe, http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/embed.htm, sollte es so nicht funktionieren.

Hat jemand Erfahrung mit dieser Art von Problem?

Wenn ich die Testanwendung starte, wird sie im Vollbild angezeigt und die eingebettete virtuelle Tastatur wird angezeigt, weil das Textfeld den Fokus hat. Das Textfeld ist in diesem Fall nicht sichtbar, bis ich die Tastatur "verstecke". Ich bin nicht sicher, dass dies der richtige Ansatz ist, also brauche ich bitte Hilfe.

java -Dcom.sun.javafx.isEmbedded=true -Dcom.sun.javafx.virtualKeyboard=javafx application.TestVKB 

public class TestVKB extends Application{ 

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

    @Override 
    public void start(Stage stage) throws Exception { 

     TextField tfComment = new TextField(); 
     tfComment.setPromptText("Enter comment"); 

     BorderPane borderPane = new BorderPane(); 
     borderPane.setBottom(tfComment); 

     Scene scene = new Scene(borderPane); 

     stage.setScene(scene); 
     stage.setMaximized(true); 
     stage.show(); 
    } 
} 

enter image description here

Nach Klick im Feld Benutzername oder Passwort enter image description here

würde ich für jeden Hinweis dankbar. Danke im Voraus.

+0

es wäre nützlich, einen Screenshot von einem überlappenden –

+0

habe ich eine weitere Erklärung hinzugefügt, denn zur Zeit kann ich keine Bilder auf den Mangel an guten Ruf aufgrund laden – Grega

+0

Versuchen Sie jetzt ein Bild hochladen. –

Antwort

2

Grundsätzlich ist die virtuelle Tastatur in eine PopupWindow eingebettet, die in einer anderen Phase erstellt und oben auf Ihrer aktuellen Bühne am unteren Bildschirmrand angezeigt wird, unabhängig davon, wo sich die InputControl befindet, die die Tastatur auslöst.

Sie können, dass auf der FXVKSkin-Klasse:

winY.set(screenBounds.getHeight() - VK_HEIGHT); 

Aber nur inmediately danach können Sie diese finden:

if (vkAdjustWindow) { 
    adjustWindowPosition(attachedNode); 
} 

es also, ist eine andere Befehlszeilenoption, die Sie verwenden können, Bewegen Sie die Bühne so, dass der Knoten (in diesem Fall das Textfeld) in der Mitte des Bildschirms liegt und Sie ihn ohne Überlappung eingeben können:

-Dcom.sun.javafx.vk.adjustwindow=true 
Hinweis

dass, wenn das Textfeld den Fokus verliert, ist die Tastatur versteckt und die Bühne bewegt wird, wieder in seine ursprüngliche Position:

restoreWindowPosition(oldNode); 

ich diese Option erfolgreich getestet haben, aber wenn Sie das Textfeld an die Unten auf dem Bildschirm bewegt sich der untere Teil der Bühne in die Mitte des Bildschirms und hinterlässt eine große Lücke zwischen beiden Stufen (Sie werden sehen, was Sie im Hintergrund haben).

Ich habe es geschafft, einen Zuhörer zu der neuen Bühne hinzuzufügen und die Position nur das Notwendige einzustellen. Wenn Sie interessiert sind, könnte ich es veröffentlichen.

EDIT

Hinweis: diese Befehlszeilenoption wird nicht funktionieren, wenn die Stufe maximiert wird.Eine einfache Lösung hierfür ist:

Rectangle2D bounds = Screen.getPrimary().getBounds(); 
stage.setX(bounds.getMinX()); 
stage.setY(bounds.getMinY()); 
stage.setWidth(bounds.getWidth()); 
stage.setHeight(bounds.getHeight()); 
stage.show(); 
+0

Zunächst einmal danke für die Antwort. Ich habe Schalter für adjustwindow, aber es gibt keinen Unterschied. Die Tastatur überlappt immer noch. Kannst du bitte so freundlich sein und deine Lösung posten? Danke vielmals. – Grega

+0

Der Grund dafür ist 'stage.setMaximized (true)'. Ich habe meine Antwort mit einer gültigen Lösung bearbeitet. –

+0

Habe es versucht und es funktioniert wirklich wie du es beschrieben hast. Die Bühne wird auf die Mitte des Bildschirms eingestellt und lässt die Lücke zwischen den Tastaturen. Wie hast du den Hörer auf die neue Bühne gebracht? Es verschiebt "Original" Bühne nur für die Höhe der Tastatur oder Größe ändern? – Grega

6

Wie ich bereits in meiner ersten Antwort darauf hingewiesen, die virtuelle Tastatur in einem PopupWindow eingebettet, in einer anderen Phase erstellt und auf der aktuellen Stufe angezeigt.

Die Option -Dcom.sun.javafx.vk.adjustwindow=true funktioniert und bewegt die Hauptbühne so, dass die Steuerung sichtbar ist und keine Überlappung vorhanden ist.

Wenn sich dieses Eingabesteuerelement jedoch am unteren Ende der Hauptbühne befindet, wird es in die Mitte des Bildschirms verschoben und hinterlässt eine große leere Lücke, die anzeigt, was sich dahinter befindet.

Diese zweite Antwort bietet eine Lösung, um die Hauptbühne nur um den erforderlichen Abstand ohne jede Lücke zu bewegen, wobei auch die Ein-/Ausblendanimationen der virtuellen Tastatur berücksichtigt werden.

Für den Anfang, in unserer Szene, fügen wir eine Button auf der Mitte, und die TextField auf der Unterseite. Mit zwei Steuerelementen können wir den Fokus leicht ändern und die Tastatur ein-/ausblenden.

Um die Bühne zu maximieren, verwende ich getVisualBounds(), damit die Taskleiste sichtbar sein kann.

private PopupWindow keyboard; 

private final Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds(); 
private final Rectangle2D bounds = Screen.getPrimary().getBounds(); 
private final double taskbarHeight=bounds.getHeight()-visualBounds.getHeight(); 

@Override 
public void start(Stage stage) { 
    TextField tfComment = new TextField(); 
    tfComment.setPromptText("Enter comment"); 

    BorderPane borderPane = new BorderPane(new Button("Click")); 
    borderPane.setBottom(tfComment); 

    Scene scene = new Scene(borderPane); 

    stage.setScene(scene); 
    stage.setX(visualBounds.getMinX()); 
    stage.setY(visualBounds.getMinY()); 
    stage.setWidth(visualBounds.getWidth()); 
    stage.setHeight(visualBounds.getHeight()); 
    stage.show(); 
} 

Wir müssen die neue Bühne finden, wenn es angezeigt wird. Auf die gleiche Weise wie Scenic View, werden wir eine veraltete Methode verwenden, um ein gültiges Fenster zu erhalten:

private PopupWindow getPopupWindow() { 

    @SuppressWarnings("deprecation") 
    final Iterator<Window> windows = Window.impl_getWindows(); 

    while (windows.hasNext()) { 
     final Window window = windows.next(); 
     if (window instanceof PopupWindow) { 
      if(window.getScene()!=null && window.getScene().getRoot()!=null){ 
       Parent root = window.getScene().getRoot(); 
       if(root.getChildrenUnmodifiable().size()>0){ 
        Node popup = root.getChildrenUnmodifiable().get(0); 
        if(popup.lookup(".fxvk")!=null){ 
         return (PopupWindow)window; 
        } 
       } 
      } 
      return null; 
     } 
    } 
    return null; 
} 

Wir diese Methode aufrufen werde, wenn das Textfeld den Fokus erhält:

... 
    stage.show(); 

    tfComment.focusedProperty().addListener((ob,b,b1)->{ 
     if(keyboard==null){ 
      keyboard=getPopupWindow(); 
     } 
    }); 
} 

Sobald wir das Fenster, können wir auf Veränderungen in seiner Position hören und die Hauptstufe entsprechend bewegen:

.... 
    stage.show(); 

    //findWindowExecutor.execute(new WindowTask()); 
    tfComment.focusedProperty().addListener((ob,b,b1)->{ 
     if(keyboard==null){ 
      keyboard=getPopupWindow(); 

      keyboard.yProperty().addListener(obs->{ 
       System.out.println("wi "+keyboard.getY()); 
       Platform.runLater(()->{ 
        double y = bounds.getHeight()-taskbarHeight-keyboard.getY(); 
        stage.setY(y>0?-y:0); 
       }); 
      }); 
     } 
    }); 
} 

Beachten sie, dass anstelle die Bühne zu bewegen, wird ein weitere Option, es wird die Größenänderung (wenn es genug Platz wi verdünnen Sie die Kontrollen).

Dies wird der Fall sein, wenn das Textfeld den Fokus und die virtuelle Tastatur wird vollständig gezeigt:

Virtual keyboard

0

ich die Lösung gefallen hat, aber in meinem Fall ziehe ich mit der Tastatur das zeigte sich zu bewegen methode getPopupWindow Ich habe einen Listener im Textfeld erstellt und die Position der Tastatur direkt geändert.

textField.focusedProperty().addListener((ob, b, b1) -> { 
     if (keyboard == null) { 
      keyboard = getPopupWindow(); 

      keyboard.setHideOnEscape(Boolean.TRUE); 
      keyboard.setAutoHide(Boolean.TRUE); 
      keyboard.centerOnScreen(); 
      keyboard.requestFocus(); 
      keyboard.sizeToScene(); 

     } 

     Platform.runLater(() -> { 
      keyboard.setY(**NEW_POSITION_OF_KEYBOARD**); 
     }); 


    });