Действительно ли JOptionPane.showMessageDialog ориентирован на многопотоковое исполнение?

Если движок шаблонов кажется большой части стычки, можно сделать движок шаблонов собственного бедного человека. Этот пример должен определенно быть улучшен и не подходит для всех задач, но для меньших сайтов могло бы подойти. Только получить Вас идея:

template.inc:

<html><head><title>%title%</title></head><body>
%mainbody%
Bla bla bla <a href="%linkurl%">%linkname%</a>.
</body></html>

index.php:

<?php
$title = getTitle();
$mainbody = getMainBody();
$linkurl = getLinkUrl();
$linkname = getLinkName();
$search = array("/%title%/", "/%mainbody%/", "/%linkurl%/", "/%linkname%/");
$replace = array($title, $mainbody, $linkurl, $linkname);
$template = file_get_contents("template.inc");
print preg_replace($search, $replace, $template);
?>
9
задан Tom Martin 20 October 2009 в 16:10
поделиться

3 ответа

Taken from the javax.swing package description:

Swing's Threading Policy

In general Swing is not thread safe. All Swing components and related classes, unless otherwise documented, must be accessed on the event dispatching thread. Typical Swing applications do processing in response to an event generated from a user gesture. For example, clicking on a JButton notifies all ActionListeners added to the JButton. As all events generated from a user gesture are dispatched on the event dispatching thread, most developers are not impacted by the restriction.

Where the impact lies, however, is in constructing and showing a Swing application. Calls to an application's main method, or methods in Applet, are not invoked on the event dispatching thread. As such, care must be taken to transfer control to the event dispatching thread when constructing and showing an application or applet. The preferred way to transfer control and begin working with Swing is to use invokeLater. The invokeLater method schedules a Runnable to be processed on the event dispatching thread.

JOptionPane does not document that it is thread safe, so you have to use invokeLater().

8
ответ дан 4 December 2019 в 10:32
поделиться

Вы должны вызывать этот метод только из потока отправки событий, так как это единственный поток, который должен взаимодействовать с компонентами Swing.

Если вы хотите приостановить фоновую обработку, ожидая обратной связи с пользователем, я предлагаю вам использовать реализацию SwingWorker , в которой doInBackground () ] периодически вызывает publish () , позволяя вызывать process () в потоке Swing. doInBackground () может затем потенциально заблокироваться до тех пор, пока в процессе () не будет выполнено какое-либо действие. Например:

new SwingWorker<Void, Void>() {
  private volatile boolean done;

  // Called on background thread
  public void doInBackground() {
    for (int i=0; i<1000000; ++i) {
      // Do work

      if (i % 1000 == 0) {
        publish(); // Will cause process() to be called on Event Dispatch thread.

        synchronized(this) {
          wait();
        }

        if (done) {
          System.err.println("Background thread stopping.");
          return null;
        }
      }
    }
  }

  // Called on Event dispatch thread.
  protected void process(List<Void> chunks) {
    if (JOptionPane.showConfirmDialog(getFrame(),
      "Do you want to quit?", "Confirm Quit",
      JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {

      done = true;        
    }

    synchronized(this) {
      notifyAll();
    }
  }
}.execute();
7
ответ дан 4 December 2019 в 10:32
поделиться

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

5
ответ дан 4 December 2019 в 10:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: