Можете ли вы определить, когда буфер обмена закрыт?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Можете ли вы определить, когда буфер обмена закрыт?

Сообщение Anonymous »

TL;DR: я хочу определять, когда другое приложение закрывает системный буфер обмена.

Сценарий
Я использую FlavorListener для переключения кнопки при изменении типа содержимого буфера обмена. Прослушиватель вызывает Clipboard#getAvailableDataFlavors, что приводит к непоследовательному выдаче исключения при копировании данных из других программ:

Код: Выделить всё

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: cannot open system clipboard
at sun.awt.windows.WClipboard.openClipboard(Native Method)
at sun.awt.datatransfer.SunClipboard.getClipboardFormatsOpenClose(SunClipboard.java:327)
at sun.awt.datatransfer.SunClipboard.getAvailableDataFlavors(SunClipboard.java:168)
MVCE
Чтобы воспроизвести проблему, запустите приведенную ниже программу и скопируйте данные в системный буфер обмена из другой программы (вам может потребоваться несколько попыток копирования, прежде чем будет создано исключение):

Код: Выделить всё

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorListener;
import java.util.Arrays;
import java.util.Scanner;

public class Foo {

public static void main(String[] args) {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
FlavorListener listener = e -> System.out.print("\rClipboard has text: "
+ Arrays.stream(clipboard.getAvailableDataFlavors()).anyMatch(DataFlavor::isFlavorTextType)
+ "\nPress enter to exit...");
clipboard.addFlavorListener(listener);

System.out.print("Press enter to exit...");
new Scanner(System.in).nextLine();
}

}
Выводы
Внутренне буфер обмена AWT использует функцию OpenClipboard из winuser.h. Согласно документации, «OpenClipboard завершается с ошибкой, если в другом окне открыт буфер обмена». Глядя на базовый код C++ для буфера обмена AWT, мы видим, что это именно причина исключения IllegalStateException.
При исследовании этого вопроса я нашел похожие вопросы:
  • В Java почему я получаю java.lang.IllegalStateException: невозможно открыть системный буфер обмена
  • прослушивать изменения в буфере обмена, проверять владельца?
В обоих сценариях решением (пришедшим из потока Coderanch) было использование Thread#sleep(long), чтобы дать время другому приложению закрыть буфер обмена.
Возражения
Я предпочитаю не полагаться на сон, поскольку нет способа точно узнать, когда (или если!) буфер обмена будет закрыт. Кроме того:
  • Если вы не спите достаточно долго, IllegalStateException все равно будет возникать.
  • Продолжительность сна, которая работает на одном компьютере, не гарантирует, что она будет работать на другом компьютере.
  • Продолжительность сна, которая успешно ожидает закрытия буфера обмена одним приложением, не гарантирует, что она будет работать для другого приложения.
  • Если вы «безопасно» и используете очень длительная продолжительность сна:
    • Пользователю, возможно, придется дождаться включения кнопки.
    • Пользователь может нажать кнопку до того, как она будет отключена (что приведет к возникновению ошибки).
  • Сон в потоке событий AWT заморозит пользовательский интерфейс, не позволяя пользователю выполнять другие действия, не зависящие от буфера обмена.
    • I придется использовать больше системных ресурсов для создания рабочего потока только для выполнения режима сна.
Вопрос
Я хотел бы знать, есть ли прослушиватель или обратный вызов, который можно зарегистрировать для выполнения, когда буфер обмена закрыт. Существует ли что-нибудь подобное?
Чтобы уточнить, я открыт для возможности написания моей собственной общей/динамически подключаемой библиотеки, если мне нужно использовать встроенную функцию для достижения этой цели.

Подробнее здесь: https://stackoverflow.com/questions/790 ... een-closed
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»