создать окно X (X11) в Java Swing и получить его идентификатор - PullRequest
3 голосов
/ 07 октября 2009

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

Ответы [ 5 ]

3 голосов
/ 07 октября 2009

Том ответил на первую часть вашего вопроса. Вторая часть ответа такова: чтобы получить идентификатор окна 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 реализована функция XFetchName, реализованная в X11, которая не была исправлена. Если вы запустили valgrind и у вас возникли незначительные проблемы с утечкой памяти, это является причиной их возникновения.

2 голосов
/ 07 октября 2015

Просто чтобы развернуть ответы @ 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 .
1 голос
/ 27 октября 2011

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

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

ВЧ

1 голос
/ 06 сентября 2010

Если вы используете 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 для перемещения окна

1 голос
/ 07 октября 2009

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

...