2009-10-20 5 views
0

Я работаю над приложением Java Swing. У меня есть кнопка, действие которой запускает запрос в базе данных, а затем отображает результаты. Эти команды выполняются из прослушивателя кнопки «Выполнить». Насколько я понимаю, это означает, что поток, выполняющийся в этой точке, находится из EventQueue.Ожидание ввода мыши в Java Swing

Учитывая определенный ввод, мне нужно прекратить обработку и ждать, пока пользователь нажмет на участок. Я изо всех сил пытаюсь найти способ сделать это. Я посмотрел на все, но я не могу найти решение, которое работает. Я попытался создать новый поток, который ждет ввода пользователя (я называю join в этом потоке). Проблема в том, что это приводит к тому, что предыдущий поток (из EventQueue) ожидает. По какой-то причине щелчки мыши не вызывают прерывания, поэтому щелчки мыши никогда не захватываются.

Любая помощь будет высоко оценена. Заранее спасибо.

ответ

5

Пусть входной сигнал EventDispatcherThread. Скорее, ваш порожденный поток должен выполнять вычисления. Я построил интерактивный интерфейс, который сделал что-то подобное год или два назад, и именно так я достиг такого поведения.

По существу, вы создаете модель производителя/потребителя между графическим интерфейсом и потоком обработки данных. Когда вход уволен, вы подаете на потребительский поток и возобновляете активность.

+0

Все, что вам нужно сделать, это создать экземпляр SwingWorker, где длинный код базы данных находится в методе doInBackground(), а последующие обновления пользовательского интерфейса находятся в методе done() и выполняют этот поток SwingWorker в ActionListener вашей кнопки. –

4

Используйте класс SwingWorker.

+0

Я построил свое приложение до 1.6. Если у вас есть доступ к 1.6, обязательно используйте SwingWorker. –

+0

К сожалению, я застрял с 1.5. У меня Mac на базе Intel, и в прошлый раз, когда я проверил, 1.6 был недоступен для меня. – Ryan

+0

SwingWorker был перенесен на 1,5. https://swingworker.dev.java.net/ – Nemi

0

Кажется, что вы делаете примерно правильную вещь, но вы не должны называть соединение в фоновом потоке из потока пользовательского интерфейса, поскольку это заморозит пользовательский интерфейс до тех пор, пока фоновый поток не завершится.

Вот это сильно сжатый пример основного метода, который я хотел бы использовать (если SwingWorker не доступен):

class QueryPerformer implements Runnable { 
    private volatile boolean plotAreaClicked; 

    public void run() { 
     // Perform query and process 
     while (!plotAreaClicked) { 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException exception) { 
       } 
     } 
     // Perform tasks following plot area click 
    } 

    public void setPlotAreaClicked(boolean plotAreaClicked) { 
     this.plotAreaClicked = plotAreaClicked; 
    } 
} 

И в ваших слушателях UI:

private QueryPerformer queryPerformer; 

public void actionPerformed(ActionEvent event) { 
    // Run button pressed 
    queryPerformer = new QueryPerformer(); 
    new Thread(queryPerformer).start(); 
} 

public void mouseClicked(MouseEvent event) { 
    // Plot area clicked 
    if (queryPerformer != null) { 
     queryPerformer.setPlotAreaClicked(true); 
    } 
} 

Пожалуйста, обратите внимание, что выше не является оптимальным, и некоторые вещи не были обработаны (например, нажатия нескольких кнопок запуска).