2013-09-27 2 views
1

У меня возникла проблема, когда JPanel берет данные от объекта, который имеет цикл, обновляющий свои переменные состояния.Перекрашивание JPanel с данными из другого объекта (поток)

Сценарий выглядит следующим образом: JFrame вызывает метод объекта, метод создает второй JFrame, имеет цикл, а затем обновляет переменную состояния. Второй JFrame получает доступ к этой переменной и должен отображаться в JPanel, но нет, GUI зависает.

Я привел проблему к примеру с таким же поведением, чтобы его можно было легко протестировать.

Я ценю любую помощь, спасибо!

Starter.java

public class Starter extends JFrame { 

    JButton button = new JButton("Fight!"); 

    public Starter() { 

     button.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       OneClass.getInstance().start(); 
      } 
     }); 
     add(button); 
    } 

    public static void main(String[] args) { 

     Starter frame = new Starter(); 

     frame.setTitle("Test"); 
     frame.setSize(400, 300); 
     frame.setVisible(true); 

    } 
} 

OneClass.java

public class OneClass { 

    private OneFrame frame; 
    private int count; 
    private static OneClass instance; 

    private OneClass() { 
    } 

    public static OneClass getInstance() { 
     if (instance == null) 
      instance = new OneClass(); 

     return instance; 
    } 

    public void start() { 
     frame = new OneFrame(); 
     frame.setSize(400, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 

     while (true) 
     { 
      count++; 
      System.out.println(count); 

      frame.repaint();    
     } 
    } 

    public int getCount() { 
     return count; 
    } 
} 

OneFrame.java

public class OneFrame extends JFrame { 

    private OnePanel panel = new OnePanel(); 

    public OneFrame() { 
     setTitle("Test frame"); 
     setContentPane(panel); 
     setResizable(false); 
    } 
} 

OnePanel.java

public class OnePanel extends JPanel { 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Font ft = new Font("Times New Roman", Font.PLAIN, 20); 
     g.setFont(ft); 

     g.drawString("Count = " + OneClass.getInstance().getCount(), 20, 20); 
    } 
} 
+0

И ваш бесконечный цикл, и графический интерфейс запускаются в одном потоке, вам нужно создать еще один поток, который управляет логикой вашего бесконечного цикла. Вот почему он висит. – porfiriopartida

+0

да ... это то, что я предполагаю, у вас есть идея, я попробую – Gabriel

ответ

3

Попробуйте это:

public Starter() { 

    button.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent arg0) { 
     new Thread() { 
      public void run() { 
      OneClass.getInstance().start(); 
      } 
     }.start(); 
     } 
    }); 
    add(button); 
    } 

Поскольку ваш цикл выполняется в том же потоке, что и GUI он свисает, как только вы достигнете бесконечный цикл.

Если вы запустите свой бесконечный цикл внутри другого потока, тогда графический интерфейс будет свободен от этого цикла.

Это не может быть лучшей многопоточная реализацией

Посмотрите параллельность учебники: http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

Теперь, так как вы используете Singleton как класс, если вы звоните в GetInstance до нити, то это может все еще висят.

+0

Спасибо! Я делал что-то подобное с циклом. – Gabriel

Смежные вопросы