Copy & Past

Dagobert

Bekanntes Mitglied
guten Abend,
Ich habe mal eine Frage: Ist es möglich wenn ich ein Fenster habe, welches "always on top" ist und dies ein z.B. JTextArea das ich aus einem anderen Programm z.B. Firefox Text kopieren kann (STR + c) und per STR+V direkt in mein Textfeld einfüge ohne dabei den Focos vom Firefox zu verlieren?

mfg. Dagobert
 

Ebenius

Top Contributor
So wie Du es beschreibst ist es unmöglich. Tastatureingaben werden immer an den Focus-Inhaber übertragen, kein anderes Programm hat damit etwas zu tun.

Ebenius
 

eRaaaa

Top Contributor
Das geht denke ich nicht. Was du aber machen könntest wäre dem ClipBoard einen FlavorListener anzuhängen, dann könntest du drauf reagieren wenn jmd mit STRG+C etwas in die Zwischenablage legt, z.B. eben den Text in dein Textfeld automatisch zu setzen....
 

Dagobert

Bekanntes Mitglied
das mit dem ClipBord und dem FlavorListener hört sich recht gut an... verstehe ich das richtig das ich Praktisch den "Str + c"-Text per listener automatisch weiterverarbeiten kann? :D

mfg. Dagobert
 

eRaaaa

Top Contributor
Denke schon
Java:
	final Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
	systemClipboard.addFlavorListener(new FlavorListener() {
	    @Override
	    public void flavorsChanged(FlavorEvent e) {
		Transferable t = systemClipboard.getContents(null);
		if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
		    try {
			String text = (String) t.getTransferData(DataFlavor.stringFlavor);
			System.out.println(text);
		    } catch (UnsupportedFlavorException e1) {
			e1.printStackTrace();
		    } catch (IOException e1) {
			e1.printStackTrace();
		    }
		}
	    }
	});
 

Ebenius

Top Contributor
Das hast Du richtig verstanden. So geht's:
Java:
final Clipboard clipboard =
      Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.addFlavorListener(new FlavorListener() {

  public void flavorsChanged(FlavorEvent e) {
    System.out.println(e);
  }
});
Hinweis: Um auf's System-Clipboard zugreifen zu dürfen, muss Deine Java-Anwendung das Recht "accessClipboard" haben. Das ist bei Anwendungen normaler Weise der Fall, bei Applets und Webstart-Anwendungen ist das i.d.R. nur möglich, wenn diese signiert sind.

Ebenius
 

Dagobert

Bekanntes Mitglied
okay ich habs jetzt mal versucht zu implementieren, jedoch stoße ich dabei auf ein großes Problem, mein Clipboard läuft absolut unzuverlässig :D
Wenn ich glück habe, und etwas z.B. in eclipse makiere und str + c drücke zeigt wird der Text angezeigt, makiere ich was anderes und drücke wieder Str + c passiert gar nichts oO und auch beim ersten aufruf ist die ausgabe nicht garantiert. Wraum nicht?

Mein Code:
Java:
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorEvent;
import java.awt.datatransfer.FlavorListener;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

import javax.swing.JFrame;

public class clipBordtest extends JFrame implements FlavorListener {

	private Clipboard clip;
	
	public clipBordtest() {
		setTitle("Clipbordtest");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		
		clip = Toolkit.getDefaultToolkit().getSystemClipboard();
		clip.addFlavorListener(this);
	}

	public static void main(String arg[]) {
		new clipBordtest();
	}

	@Override
	public void flavorsChanged(FlavorEvent e) {
		if(e.getSource().equals(clip)){
			System.out.println("clippord");
			Transferable trans = clip.getContents(null);
			if(trans != null && trans.isDataFlavorSupported(DataFlavor.stringFlavor)){
				try {
					System.out.println(trans.getTransferData(DataFlavor.stringFlavor));
				} catch (UnsupportedFlavorException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	}
}

mfg. Dagobert
 

eRaaaa

Top Contributor
Ja das ist mir auch aufgefallen. Liegt wohl daran, dass das Event nur bei Änderungen des DataFlavors horcht, aber nicht auf den Content, also Inhalt...Ich glaube dafür gibts noch keine wirklich "gute" Lösung..man könnte vllt selbst jedes mal pollen oder so?! Vllt weiß Ebenius da mehr
 

Dagobert

Bekanntes Mitglied
okay ich habe hier mal einen Handweg gebaut der das ganze auch schon macht:

Java:
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;

public class clipBordtest extends JFrame implements ActionListener {

	private Clipboard clip = null;
	Transferable old = null;
	Timer t;

	public clipBordtest() {
		setTitle("Clipbordtest");
		setAlwaysOnTop(true);
		setSize(new Dimension(250, 250));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		
		clip = Toolkit.getDefaultToolkit().getSystemClipboard();
		old = clip.getContents(null);
		
		t = new Timer(500, this);
		t.start();
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		Transferable trans = clip.getContents(null);
		try {
			if (trans.isDataFlavorSupported(DataFlavor.stringFlavor) && trans != null && !trans.getTransferData(DataFlavor.stringFlavor).equals(old.getTransferData(DataFlavor.stringFlavor))) {
				System.out.println("Old: " + old.getTransferData(DataFlavor.stringFlavor));
				System.out.println("New: " + trans.getTransferData(DataFlavor.stringFlavor));
				old = trans;
			}
		} catch (UnsupportedFlavorException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	public static void main(String arg[]) {
		new clipBordtest();
	}
}

mfg. Dagobert
 

eRaaaa

Top Contributor
Joah...aber
Java:
trans.isDataFlavorSupported(DataFlavor.stringFlavor) && trans != null ......

so bringt die Abfrage auf null natürlich nichts, da du ja vorher schon eine Methode auf trans aufrufst :D
Drehe die beiden mal um..
 

Ebenius

Top Contributor
Seltsam. Ein Windows hab ich grad nicht zur Hand. Aber auf meinem Linux funktioniert der von mir gepostete Code bei jedem Inhaltswechsel; selbst wenn der exakt selbe Inhalt von der selben Applikation wiederholt in die Zwischenablage gelegt wird.

[Edit] Da hab ich mich wohl verguckt; funktioniert auch bei mir nicht. :) Eine Idee habe ich noch, aber die muss ich mir erstmal ansehen, melde mich dann nochmal.

[Edit2] Unsinn war's. Geht leider doch nicht.

Ebenius
 
Zuletzt bearbeitet:

eRaaaa

Top Contributor
Ich habe eben noch einen alten Thread von 2007 gefunden wo Wildcard einen Link zum Bug/oder was auch immer das ist, gepostet hatte --> Bug ID: 4259272 Support Notifications of Clipboard Contents Changes.
Da sind einige Vorschläge dabei...den Content zu holen und dann immer dann den ClipBoardinhalt zu leeren bzw den Owner zu ändern?! ist aber nicht so toll wie ich finde oder?
Also
Java:
		    public void flavorsChanged(FlavorEvent e) {
		System.out.println(e);
		clipboard.setContents(clipboard.getContents(null),null);
	    }

Wenn jetzt andere Programme auch auf das ClipBoard hören würden, wäre das ja nicht so prall...(funktionieren tut`s allerdings bei mir :D )
 

Ebenius

Top Contributor
Das war auch meine Idee. Allerdings hat das zur Folge, dass manche Sachen danach nicht mehr funktionieren werden. Denn jedes Programm darf sobald es die Nachricht erhält, dass es nicht mehr Clipboard-Eigentümer ist, alles vergessen, was nötig wäre, um den Transfer abzuschließen. Und stets den gesamten Clipboard-Inhalt zu kopieren und das Clipboard zu übernehmen ist ebenfalls unmöglich. :-(

Ebenius
 

Ähnliche Java Themen

Neue Themen


Oben