JTextField Context Menue fuer Applets..?

Status
Nicht offen für weitere Antworten.

sirbender

Top Contributor
Hi,

ich habe ein JTextfield. Ich kann dessen Text markieren und per Ctrl+C in das System Clipboard schicken. Nun habe ich mir diese Copy Action aus der ActionMap des TextFields geholt und feuere Sie wenn der User im JTextField ContextMenue (rechte Maustaste) auf eine Copy-JMenuItem klickt.

Funktioniert alles prima.

Was passiert wenn ich es als Applet laufen lasse? Ctrl+C per Tastendruck funktioniert immer noch: der kopierte Text landet im Clipboard.

Was nicht mehr funktioniert ist das Context-Menue. Es wirft keinen Fehler. Der kopierte Text landet einfach nicht mehr im Clipboard.

Kann mir jemand die Codestelle zeigen an der in Applets entschieden wird - ok dieses Event kommt von einem Tastendruck - d.h. es wird ausgefuehrt?

Vielen Dank,
sb
 
Gib mal ein ganz kleines Stück Beispielquelltext wie das JPopupMenu für die COPY-Action aufgebaut wird.

Ebenius
 
Wird denn die Action ausgeführt? Kannst mal den Code in etwa so anpassen:
Java:
final Action a = textField.getActionMap().get(DefaultEditorKit.copy);
popupMenu.add(new AbstractAction("Check if clipboard copy works") {
  public void actionPerformed(ActionEvent e) {
    System.out.println("Action performed");
    System.out.println("Copy action is " + (a == null ? "not " : "") + "available");
    if (a != null) {
      a.actionPerformed(e);
    }
  }
});
Und dann die Ausgaben anschauen.

Ebenius
 
Wird denn die Action ausgeführt? Kannst mal den Code in etwa so anpassen:
Java:
final Action a = textField.getActionMap().get(DefaultEditorKit.copy);
popupMenu.add(new AbstractAction("Check if clipboard copy works") {
  public void actionPerformed(ActionEvent e) {
    System.out.println("Action performed");
    System.out.println("Copy action is " + (a == null ? "not " : "") + "available");
    if (a != null) {
      a.actionPerformed(e);
    }
  }
});
Und dann die Ausgaben anschauen.

Ebenius

Die CopyAction ist nicht null an diesem Punkt. Das Problem ist eher, dass ein unsigniertes/sandboxed Applet nicht zulaesst, dass man Text ins System Clipboard via Action bugsiert.
Die einzige Moeglichkeit dies zu tun scheint ueber direktes druecken von Ctrl+C zu sein. Wird die Action irgendwie sonst ausgeloest scheint diese 'consumiert' zu werden. Ich wuerde nur gerne wissen an welcher Stelle im Code entschieden wird, dass die Action konsumiert werden soll.
 
Ich hab's eben mal mit dem Opera probiert, der ja eine JVM ohne Netscape-Plugin benutzt. Im Opera kann mein unsigniertes Applet überhaupt kein Copy ins System-Clipboard. Im Firefox ist's wie von Dir beschrieben. Der entsprechende Code liegt in der TransferHandler-Klasse:
Java:
	/**
	 * Returns the clipboard to use for cut/copy/paste.
	 */
        private Clipboard getClipboard(JComponent c) {
	    if (SwingUtilities2.canAccessSystemClipboard()) {
		return c.getToolkit().getSystemClipboard();
	    }
	    Clipboard clipboard = (Clipboard)sun.awt.AppContext.getAppContext().
		get(SandboxClipboardKey);
	    if (clipboard == null) {
		clipboard = new Clipboard("Sandboxed Component Clipboard");
		sun.awt.AppContext.getAppContext().put(SandboxClipboardKey,
						       clipboard);
	    }
	    return clipboard;
	}
Das System-Clipboard ist nicht erreichbar, also nehme ich an, dass das Netscape-Plugin einen AppletContext zur Verfügung stellt der Voodoo macht, wenn das letzte Event ein Tastatur-Event war, oder sowas. Die Action wird auf jeden Fall ausgeführt; der Event also nicht verschluckt. Copy funktioniert bestimmt auch mit Kontextmenü, wohl nur innerhalb desselben Applets.

Ebenius
 
Ich hab's eben mal mit dem Opera probiert, der ja eine JVM ohne Netscape-Plugin benutzt. Im Opera kann mein unsigniertes Applet überhaupt kein Copy ins System-Clipboard. Im Firefox ist's wie von Dir beschrieben. Der entsprechende Code liegt in der TransferHandler-Klasse:
Java:
	/**
	 * Returns the clipboard to use for cut/copy/paste.
	 */
        private Clipboard getClipboard(JComponent c) {
	    if (SwingUtilities2.canAccessSystemClipboard()) {
		return c.getToolkit().getSystemClipboard();
	    }
	    Clipboard clipboard = (Clipboard)sun.awt.AppContext.getAppContext().
		get(SandboxClipboardKey);
	    if (clipboard == null) {
		clipboard = new Clipboard("Sandboxed Component Clipboard");
		sun.awt.AppContext.getAppContext().put(SandboxClipboardKey,
						       clipboard);
	    }
	    return clipboard;
	}
Das System-Clipboard ist nicht erreichbar, also nehme ich an, dass das Netscape-Plugin einen AppletContext zur Verfügung stellt der Voodoo macht, wenn das letzte Event ein Tastatur-Event war, oder sowas. Die Action wird auf jeden Fall ausgeführt; der Event also nicht verschluckt. Copy funktioniert bestimmt auch mit Kontextmenü, wohl nur innerhalb desselben Applets.

Ebenius


Danke. Du meinst also innerhalb eines Applets kann ich zwischen Text-Componenten kopieren. Ich hab das grade probiert und es klappt.

Ich denke mal man kann dem System nicht vorgaukeln dass das Event von einem Keypress kommt? KeyPress-Events schaffen es ja das System Clipboard zu benutzen.

Btw - kannst du mir genauere Info geben was Opera als Java Plugin nutzt? Die nutzen direkt die JVM? Ich habe naemlich extrem anderes Verhalten bei Applets mit Opera.

Eines meiner Applets laeuft erst gar nicht, da es eine Library von einer 2ten Domain laedt. Alle anderen Plugin/Browser Kombinationen schaffen das. Ich glaube Opera nutzt da seinen eigenen Classloader der das nicht zulaesst. Ich weiss ich kann das nicht umgehen. Trotzdem - rein aus Intresse bin ich also dankbar fuer alle Info ueber das Opera Java Plug-in...auch warum Opera diesen Schritt gegangen ist und was anderst ist.

Nochmals Danke,
sb
 
Btw - kannst du mir genauere Info geben was Opera als Java Plugin nutzt? Die nutzen direkt die JVM? Ich habe naemlich extrem anderes Verhalten bei Applets mit Opera.
Kann ich mir vorstellen und habe ich selbst schon mit (anderer Leute) Applets festgestellt. Aber Details hab ich dazu nicht. Ich weiß auch nicht, wie das Opera unter Windows tut, auf meinem Linux startet er das java binary. Wie Du an meinen seltsamen Antworten oben siehst, habe ich kaum Erfahrung in der Entwicklung von Applets. 🙂 Ich mache eigentlich meist Swing-Anwendungen die mit Webstart starten.

Ebenius
 
Kann ich mir vorstellen und habe ich selbst schon mit (anderer Leute) Applets festgestellt. Aber Details hab ich dazu nicht. Ich weiß auch nicht, wie das Opera unter Windows tut, auf meinem Linux startet er das java binary. Wie Du an meinen seltsamen Antworten oben siehst, habe ich kaum Erfahrung in der Entwicklung von Applets. 🙂 Ich mache eigentlich meist Swing-Anwendungen die mit Webstart starten.

Ebenius

ah ok. Kein Problem. Uebrigens stelle ich beim Debuggen fest dass das Applet fuer JTextFields eine DefaultEditorKit.CopyAction benutzt und keinen TransferHandler...oder habe ich da was missverstanden?
 
[...] dass das Applet fuer JTextFields eine DefaultEditorKit.CopyAction benutzt und keinen TransferHandler
Das ist alles etwas kompliziert. Die [c]CopyAction[/c] ruft die [c]copy()[/c]-Methode des [c]JTextComponent[/c] auf, diese wiederum guckt in der eigenen [c]ActionMap[/c] nach, ob eine Aktion namens [c]copy[/c] registriert ist und ruft diese Aktion auf, oder -- falls es eine solche nicht gibt -- die Kopieraktion ([c]TransferAction[/c]) des [c]TransferHandlers[/c]. Falls es eine Aktion mit Namen [c]copy[/c] in der [c]ActionMap[/c] gibt, kopiert diese normaler Weise auch über den [c]TransferHandler[/c].

Ebenius
 
Das ist alles etwas kompliziert. Die [c]CopyAction[/c] ruft die [c]copy()[/c]-Methode des [c]JTextComponent[/c] auf, diese wiederum guckt in der eigenen [c]ActionMap[/c] nach, ob eine Aktion namens [c]copy[/c] registriert ist und ruft diese Aktion auf, oder -- falls es eine solche nicht gibt -- die Kopieraktion ([c]TransferAction[/c]) des [c]TransferHandlers[/c]. Falls es eine Aktion mit Namen [c]copy[/c] in der [c]ActionMap[/c] gibt, kopiert diese normaler Weise auch über den [c]TransferHandler[/c].

Ebenius

Was ich nicht verstehe ist, warum man nicht den System vorgaukeln kann, dass der Mausklick ein Keypress ist und er somit das Ergebnis in das System Clipboard schreiben soll. Wo genau wird unterschieden woher der copy Befehl kommt?

Ist ein KeyEvent zu tief verwurzelt in AWT als das sich da was machen laesst?
 
Ich kann es Dir nicht sagen. Wie bereits erwähnt; ich gehe davon aus, dass das Netscape-Plugin einen AppletContext zur Verfügung stellt, der in dem Fall, dass der Benutzer tatsächlich COPY gewählt hat, die Aktion zulässt. Selbst wenn man das umgehen könnte, müsste man dann einen Bug an Sun melden, dass sie dieses Sicherheitsloch schließen. ;-)

Ebenius
 
Ich kann es Dir nicht sagen. Wie bereits erwähnt; ich gehe davon aus, dass das Netscape-Plugin einen AppletContext zur Verfügung stellt, der in dem Fall, dass der Benutzer tatsächlich COPY gewählt hat, die Aktion zulässt. Selbst wenn man das umgehen könnte, müsste man dann einen Bug an Sun melden, dass sie dieses Sicherheitsloch schließen. ;-)

Ebenius

Das hab ich mir schon gedacht...auch denke ich dass die Sache recht wasserdicht ist.

Vielen Dank fuer deine Hilfe 🙂
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben