Создать окно X (X11) в Java Swing и получить его идентификатор

Может ли кто-нибудь помочь мне в создании окна X11 в java swing с использованием eclipse? А также функции для получения идентификатора x11. Каковы основные требования для создания окна X11 в java.

5 ответов

Том ответил на первую часть вашего вопроса. Вторая часть ответа такова: чтобы получить идентификатор окна X11, вам нужно использовать собственный код (код, написанный на C или C++) и обращаться к нему через интерфейс JNI.

Возможно, вам придется запустить поиск по заголовку во всех существующих окнах, чтобы получить то, что вы хотите.

Вот рекурсивная функция, которая будет искать (начиная с корневого окна) окно с нужным именем

Window windowWithName(Display *dpy, Window top, char *name)
{
    Window *children, dummy;
    unsigned int nchildren;
    unsigned int i;
    Window w = 0;
    char *window_name;

    if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name))
        return (top);

    if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren))
        return (0);

    for (i = 0; i < nchildren; i++)
    {
        w = windowWithName(dpy, children[i], name);
        if (w)
            break;
    }
    if (children)
        XFree((char *) children);
    return (w);
}

Примечание: ** к сожалению, в функции XFetchName, реализованной в X11, утечка памяти была хорошо документирована, но она никогда не была исправлена. Если вы запустили valgrind и у вас возникли незначительные проблемы с утечкой памяти, это является причиной их возникновения

Просто чтобы расширить ответы, Zubzub дали Zubzub и ArtemGr, у меня работает следующий минималистичный пример AWT, по крайней мере, в Sun Java 1.8:

import java.awt.Dimension;

import javax.swing.JFrame;

import sun.awt.X11.XWindow;

class C {
    public static void main(final String args[]) {
        final JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(200, 200));
        frame.pack();
        frame.setVisible(true);
        final XWindow xWindow = (XWindow) frame.getPeer();
        frame.setTitle("Window id: 0x" + Long.toHexString(xWindow.getWindow()));
    }
}

Как только окно станет видимым, вы можете проверить его идентификатор с помощью xwininfo полезность.

Обратите внимание, однако, что даже если ваше приложение AWT будет работать только под X11, вышеприведенное решение не переносимо:

  • GCJ будет использовать gnu.java.awt.peer.gtk.GtkFramePeer, а также
  • старые версии Sun JDK (1.4 и ниже) будут использовать sun.awt.motif.MFramePeer, Несмотря на XToolkit по умолчанию в Sun JDK, начиная с 1.5, по умолчанию MToolkit все еще можно включить на 1.5 и 1.6, и
  • Я не уверен насчет IBM J9, BEA JRockit, Oracle lwAWT и Apache Harmony.

Создать окно X11 в Swing так же просто, как new Frame() с последующим setVisible(true), Получить какие-либо непредвзятые детали будет сложнее. Конечно, вы всегда можете открыть java.net.Socket к порту 6000 или около того и говорите сами X11.

Для тех, кто еще ищет это:

Вам нужно найти самый верхний компонент вашей программы и получить компонентный компонент. В Linux это будет иметь тип XComponent peer, который расширяет XWindow, который расширяет XBaseWindow. XBaseWindow имеет окно атрибутов типа long. Это то, что вы ищете. Вы, вероятно, должны использовать отражение, чтобы добраться до него.

высокочастотный

Если вы используете Sun JVM и не возражаете против переопределения доступа к пакету с помощью отражений и "setAccessible(true)", то вы можете создать окно X11 с помощью инструментария Sun. https://www.docjar.com/docs/api/sun/awt/X11/XWindow.html

Однако могут присутствовать не все методы инструментария: я подозреваю, что методы, не используемые в самом инструментарии, были удалены. Например, большая часть XlibUtil отсутствует. Вот пример того, как использовать отражение для доступа к методам инструментария, в Scala: http://gist.github.com/567076

Вы также можете использовать JNA для кодирования частей xlib в Java; см. вопрос: Использование Xlib через JNA для перемещения окна

Другие вопросы по тегам