Получаване на JOptionPane.showConfirmDialog() за функциониране на Mac OSX

Имам проблеми с показването/функционирането на полета за съобщения и до известна степен диалогови прозорци в Mac (v10.9.5).

Току-що актуализирах JRE и JDK до най-новата версия (8u31). „Java -version“ от терминален прозорец показва, че наистина използвам 8u31. (Преди това използвах 8u20, който показа същото поведение.)

Кодът по-долу работи перфектно в Windows и няколко различни версии на Linux, които тествах, без проблеми. Просто имам проблеми с Mac. Опростих моя код, който е базиран на SWT, но този пример използва Swing, до следното:

package myTest;

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class EntryCode
{
    public static EntryCode oEntryCode;

    public EntryCode()
    {
        // TODO Auto-generated constructor stub
    }

    public static void main(String[] args)
    {
        oEntryCode = new EntryCode();

        oEntryCode.open();
    }

    public void open()
    {
        JPanel panel = new JPanel();
        panel.setMinimumSize(new Dimension(200,200));

        JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
        System.out.println("open(): entry - With frame");
        JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
        System.out.println("Point 1");

        System.exit(0);
    }
}

Виждам първия изходен ред на системата и кодът виси на заявката за полето за съобщения. В реалния код просто използвам нула като първи аргумент. Оригиналната версия на този тестов код също използваше нула, просто експериментирах с посочването на компонент. Мислех, че това може да е проблемът. Не е.

При показване на SWT диалогови прозорци има тенденция щракването върху бутон да увисне на интерфейса. Зависването е някъде между натискането на бутона и задействането на манипулатора на събития. Манипулаторът на събитие никога не се задейства.

Тук не съм включил диалогов прозорец. Предполагам, че тъй като моето поле за потвърждение/съобщение показва същия проблем, който решава едното, вземете другото безплатно.

Направих търсене в Google за показване на java приложения на Mac, но нищо не се появи.

Мисля, че актуализирането на JRE/JDK до най-новата версия ще реши всички проблеми, свързани с ОС.

Компилирам кода в буркан и използвам следното, за да стартирам от терминален прозорец. Трябва да натисна Ctrl+C, за да затворя приложението.

java -XstartOnFirstThread -jar myTest.jar

мисли?

АКТУАЛИЗАЦИЯ:

Изтрих оригиналната актуализация, но оставям първоначалния въпрос, сега, когато разбирам проблема по-добре.

Истинският проблем е как да стартирате подходящо SWT приложение за ограничения на Mac OSX Cocoa, което използва диалогови прозорци и прозорци за съобщения. (Доколкото ми е известно, единственият начин за показване на кутии за съобщения е да се използва JOptionPane.show*, което е нещо на Swing, като по този начин смесва Swing и SWT.

Интересно е да се отбележи, че проблемът винаги е свързан с бутони, независимо дали е в диалогов прозорец (чисто изпълнение на SWT) или кутии за съобщения. В първото проблемът е увисване, извикващо манипулатора на събития, а второто показва поле за съобщение (нулев първи аргумент, тъй като в SWT приложение не съществува Swing рамка).


person Sarah Weinberger    schedule 17.02.2015    source източник


Отговори (2)


Не съм съвсем сигурен дали това може да е грешката, тъй като в момента не мога да го тествам на моя Mac. Но никога не задавате видимостта на JFrame на true. Когато подадете рамката като параметър към JOptionPane, прозорецът се опитва да покаже панела в рамката.

Така че опитайте:

 public void open()
{
    JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
    System.out.println("open(): entry - With frame");
    frame.setSize(300,300);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
    System.out.println("Point 1");

    System.exit(0);
}

Освен това защо създавате JPanel, панелът никога не се използва, доколкото виждам?

Тъй като рамката не се вижда, това може да причини проблеми. Само предположение... Това също би обяснило защо изглежда, че приложението ви "замръзва". Причината е, че чака да направите избор във вашия JOptionPane, но не можете да направите този избор, защото не можете да видите JOptionPane.

Знам, че писахте, че също сте опитали с предаване на null като аргумент, но мога да си помисля, че това също може да причини проблеми, когато няма показан друг JFrame. Както казах само предположение. Просто го изпробвайте и се върнете тук, за да предоставите допълнителна информация.

РЕДАКТИРАНЕ Току-що тествано и изглежда, че кодът ви е наред. Вашата грешка трябва да е в настройката на вашия mac или java.

РЕДАКТИРАНЕ 2 Мисля, че намерих отговора ви. Изглежда, че startOnFirstThread е проблемът тук. Току-що тествах чрез javac и java на командния ред. Разгледайте това:

Swing спира да работи, защото -XstartOnFirstThread предполага, че този
някой друг (много вероятно SWT) ще се появи и ще започне
да изпомпва цикъла на събитията в нишка 0 с CFRunLoop или други подобни

Това може да обясни защо вашият JOptionPane се бори да се покаже. (Взето от: тук

Също малко по-стар, но описва вашия проблем:

Проблемите с AWT обикновено се свеждат до това в коя нишка е стартиран jvm. Когато използвате програмата за стартиране на java (както прави pde) на Mac, java по подразбиране стартира от втората нишка (което иска AWT), освен ако не посочите -XstartOnFirstThread (което иска SWT). https://bugs.eclipse.org/bugs/show_bug.cgi?id=212617

person dehlen    schedule 18.02.2015
comment
Ще мога да тествам на моя Mac след около 30 минути. Ще се свържа с вас тогава. О, също така, моля, уверете се, че нямате зададени точки на прекъсване. - person dehlen; 18.02.2015
comment
Благодаря, но не изпълнявам кода в Eclipse на Mac. Създавам кода на Windows и използвам Ant за създаване на jar файл. След това TeamViewer в Mac и копирам jar файла в папка. След това използвам java -XstartOnFirstThread -jar ‹my jar файл›, за да стартирам приложението от терминален прозорец. Няма Eclipse, така че не е възможно да се зададе точка на прекъсване. - person Sarah Weinberger; 18.02.2015
comment
Току-що компилирах и стартирах вашата програма на моя Mac и всичко работи добре. Изглежда, че нещо в настройката на вашия mac/java не е наред. - person dehlen; 18.02.2015
comment
Опитах кода на друг Mac без резултат; същия проблем. Опитах няколко варианта (с/без стартиране и т.н.) и получих абсолютно същото поведение като на първата машина Mac. Разбирам, че кодът е работил на компютъра на Dehlen, въпреки че не съм тествал неговия конкретен двоичен файл, нито той е тествал моя. - person Sarah Weinberger; 19.02.2015
comment
SwingUtilities.invokeLater не може да се използва с SWT приложения и цикъл на съобщения на Mac поради ограниченията на Cocoa. Създаването на рамка и използването й също не е опция, защото вече имам видима рамка. Това се нарича моето приложение, базирано на SWT. Това ме оставя в началото. - person Sarah Weinberger; 19.02.2015
comment
Използвайте swt компоненти или swing компоненти, но не и двете. Толкова е лесно - person dehlen; 19.02.2015
comment
Добре, но увисванията на Mac/OSX са свързани с бутони: 1) чрез полето за съобщения 2) натискания на бутони в SWT диалогови прозорци. Няма Swing в SWT диалог. Доколкото ми е известно, човек трябва да използва JOptionPane за кутии за съобщения в SWT, нещо Swing. - person Sarah Weinberger; 19.02.2015
comment
В SWT използвате MessageDialog swt компонент. - person dehlen; 19.02.2015
comment
Проблемът беше смесването на SWT и Swing. Веднага след като премахнах всички следи от Swing и намерих SWT реализация за кутии за съобщения, Mac започна да функционира правилно. Тестовият код на Swing работи перфектно, ако следва протокола на Swing (няма -XstartOnFirstThread, стартирайте за стартиране на отделна нишка и видимата рамка). - person Sarah Weinberger; 20.02.2015

Проблемът може да е, че не стартирате GUI в EDT. Опитайте тази:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            oEntryCode = new EntryCode();
            oEntryCode.open();
        }
    });
}

Повече информация: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html

Друг проблем е използването на -XstartOnFirstThread със Swing. Swing прави еквивалента на това, което прави -XstartOnFirstThread, но по свой начин. Не трябва да използвате -XstartOnFirstThread със Swing, точно както не е добра идея да смесвате SWT и Swing.

Ако добавите SwingUtilities.invokeLater() и премахнете -XstartOnFirstThread, вашият пример трябва да работи нормално.

person martinez314    schedule 17.02.2015
comment
Гласуването от някого беше преждевременно. Тестването показа, че не върви, за съжаление. - person Sarah Weinberger; 18.02.2015