Cannot open system clipboard exception thrown on setCaretPosition

3.7k views Asked by At

I have JEditorPane (communicationView) in my Swing application, and sometimes I need scroll it to the bottom. Scrolling is done by setting caret position to the document end.

private void setCommunicationViewCaretPosition(){

        communicationView.setCaretPosition(communicationView.getDocument().getLength());

    }

This usually works, but after a while following exception gets thrown:

Exception in thread "Thread-6" java.lang.IllegalStateException: cannot open system clipboard
        at sun.awt.windows.WClipboard.openClipboard(Native Method)
        at sun.awt.datatransfer.SunClipboard.getClipboardFormatsOpenClose(SunClipboard.java:332)
        at sun.awt.datatransfer.SunClipboard.isDataFlavorAvailable(SunClipboard.java:192)
        at org.jdesktop.application.TextActions.updateTextActions(TextActions.java:132)
        at org.jdesktop.application.TextActions.access$400(TextActions.java:47)
        at org.jdesktop.application.TextActions$TextComponentCaretListener.caretUpdate(TextActions.java:115)
        at javax.swing.text.JTextComponent.fireCaretUpdate(JTextComponent.java:407)
        at javax.swing.text.JTextComponent$MutableCaretEvent.fire(JTextComponent.java:4417)
        at javax.swing.text.JTextComponent$MutableCaretEvent.stateChanged(JTextComponent.java:4439)
        at javax.swing.text.DefaultCaret.fireStateChanged(DefaultCaret.java:802)
        at javax.swing.text.DefaultCaret.changeCaretPosition(DefaultCaret.java:1277)
        at javax.swing.text.DefaultCaret.handleSetDot(DefaultCaret.java:1173)
        at javax.swing.text.DefaultCaret.setDot(DefaultCaret.java:1154)
        at javax.swing.text.DefaultCaret.setDot(DefaultCaret.java:1051)
        at javax.swing.text.JTextComponent.setCaretPosition(JTextComponent.java:1680)
        at aau.application.ApplicationView.setCommunicationViewCaretPosition(ApplicationView.java:643)

I can't figure out why is this happening, or what setting caret position has to do with system clipboard.

Setting caret position seems to be the best way to scroll down the view but any other method would solve my problem.

2

There are 2 answers

0
User On

To access the clipboard:

Create a class file with this text

import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.Toolkit;
import java.io.*;

public final class clipboardData implements ClipboardOwner {

  public static void main(String...  aArguments ){
    clipboardData Clipboard = new clipboardData();
  }

   /**
   * Empty implementation of the ClipboardOwner interface.
     * @param aClipboard
     * @param aContents
   */
   @Override
   public void lostOwnership(Clipboard aClipboard, Transferable aContents){
     //do nothing
   }

  /**
  * Place a String on the clipboard, and make this class the
  * owner of the Clipboard's contents.
     * @param aString
  */
  public void setData(String aString){
    StringSelection stringSelection = new StringSelection(aString);
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents(stringSelection, this);
  }

  /**
  * Get the String residing on the clipboard.
  *
  * @return any text found on the Clipboard; if none found, return an
  * empty String.
  */
  public String getData() {
    String result = "";
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    //odd: the Object param of getContents is not currently used
    Transferable contents = clipboard.getContents(null);
    boolean hasTransferableText =
  (contents != null) &&
  contents.isDataFlavorSupported(DataFlavor.stringFlavor);
    if (hasTransferableText) {
      try {
        result = (String)contents.getTransferData(DataFlavor.stringFlavor);
      }
      catch (UnsupportedFlavorException | IOException ex){
        System.out.println(ex);
        ex.printStackTrace();
      }
    }
    return result;
  }
}

The code above is accessible with this functions:

Create a new clipboard editor:

clipboardData clipboardData = new clipboardData();

setData function:

clipboardData.setData(Data);

getData function:

clipboardData.getData();
0
camickr On

and sometimes I need scroll it to the bottom.

Why? Are you scrolling because you just added new text and you want to see the text your just added, or do you have a "Scroll to Bottom" button.

In the first case you can check out Text Area Scrolling for a suggestion. I normally use a JTextArea or JTextPane to display text. A JEditorPane is used for HTML only so I'm not sure if this suggestion will work.

For the second case you can just use the vertical scrollbar and set it value to the scrollbar maximum value.