2015-03-02 5 views
1

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

Меню опций:

public class BootScreen extends JPanel implements ActionListener { 

GridBagConstraints c = new GridBagConstraints(); 

JFrame frame = new JFrame(); 

SpinnerNumberModel arraySizeModel = new SpinnerNumberModel(50, 0, 100000, 1); 
SpinnerNumberModel speedModel = new SpinnerNumberModel(20, 0, 10000, 1); 
SpinnerNumberModel algSelectModel = new SpinnerNumberModel(1, 1, 5, 1); 

JSpinner arraySizeSpinner = new JSpinner(arraySizeModel); 
JSpinner speedSpinner = new JSpinner(speedModel); 
JSpinner algSelectSpinner = new JSpinner(algSelectModel); 

JButton start = new JButton("Start"); 

BootScreen() { 
    frame.setTitle("Settings"); 
    frame.setSize(500, 250); 
    frame.setVisible(true); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    frame.add(this); 

    //just creating the options menu, nothing special here (deleted for simplicity) 
    //... 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    Algorithm alg = new Algorithm(Integer.parseInt(arraySizeModel.getValue().toString()), Integer.parseInt 
      (speedModel.getValue().toString())); 

    switch(Integer.parseInt(algSelectModel.getValue().toString())) { 
     case 1: 
      alg.alg1(); 
      break; 

     case 2: 
      alg.alg2(); 
      break; 

     case 3: 
      alg.alg3(); 
      break; 

     case 4: 
      alg.alg4(); 
      break; 

     case 5: 
      alg.alg5(); 
      break; 
    } 
} 

public static void main(String[] Args) {new BootScreen();} 
} 

Основные алгоритм питания:

public class Algorithm { 
int[] A; 
GUI gui; 
int type; 
int[] pointers; 
int delay; 
int max; 

Random r = new Random(); 

Algorithm(int arraySize, int delaySet) { 
    A = new int[arraySize]; 
    delay = delaySet; 
    gui = new GUI(this); 
} 

void generate(int maxIntSize, int pointersAmount, int typeSet) { 
    max = maxIntSize; 
    for(int i = 0; i < A.length; i++) { 
     A[i] = r.nextInt(max); 
    } 

    pointers = new int[pointersAmount]; 
    for(int i = 0; i < pointers.length; i++) { 
     pointers[i] = -1; 
    } 
    type = typeSet; 
} 

void step(boolean sleep, int updatePointer, int updatePointerVal) { 
    pointers[updatePointer] = updatePointerVal; 
    gui.revalidate(); 
    gui.repaint(); 
    if(sleep) { 
     try { 
      Thread.sleep(delay); 
     }catch(InterruptedException e) { 
     } 
    } 
} 

//alg1(), alg2(), .... would be here. They first call generate() and call step() a couple of times. (deleted for simplicity) 
} 

ГИП:

public class GUI extends JPanel { 
JFrame frame = new JFrame(); 
Algorithm alg; 

GUI(Algorithm algIn) { 
    alg = algIn; 

    frame.setTitle("Algorithmizer"); 
    frame.setSize(1080, 720); 
    frame.setExtendedState(Frame.MAXIMIZED_BOTH); 
    frame.setVisible(true); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    frame.add(this); 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    //drawing alg.A as a bar-graph by looping through it (deleted for simplicity) 
} 
} 

Когда я ставил System.out.println («1») перед вызовом repaint(), System.out.println («2») в функции paintComponent() и System.out.println ("3") после перекраски() называют это будет только печать: ... Я также попытался напечатать стек, не получил что-нибудь полезное от этого. Программа перерисовывает, когда алгоритм сделан, но это не полезно для меня.

+0

Id предлагает не делать тяжелой работы без использования SwingWorker – user489041

ответ

0

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

@Override 
public void actionPerformed(ActionEvent e) { 
    new SwingWorker<Object, Object>() { 
      @Override 
      protected Object doInBackground() throws Exception { 
       runAlg(); 
       return null 
      } 

      @Override 
      protected void done() { 
       //any of you gui stuff here 
      } 
     }.execute(); 
    } 
} 

public void runAlg(){ 
    Algorithm alg = new Algorithm(Integer.parseInt(arraySizeModel.getValue().toString()), Integer.parseInt 
      (speedModel.getValue().toString())); 

    switch(Integer.parseInt(algSelectModel.getValue().toString())) { 
     case 1: 
      alg.alg1(); 
      break; 

     case 2: 
      alg.alg2(); 
      break; 

     case 3: 
      alg.alg3(); 
      break; 

     case 4: 
      alg.alg4(); 
      break; 

     case 5: 
      alg.alg5(); 
      break; 
    } 
} 
0

Проблема заключается в том, что она не будет перекрашивать больше до алгоритма заканчивается.

Ваш алгоритм выполняется на Event Dispatch Thread (EDT), который является Пропустите GUI использует для рисования себя, поэтому GUI не может перерисовать себя, пока алгоритм не будет завершен.

Решение заключается в использовании отдельного потока для алгоритма.

Один из способов сделать это - использовать Swing Worker, который выполняется в отдельном потоке и позволяет «публиковать» результаты по мере выполнения алгоритма.

Для получения более подробной информации ознакомьтесь с разделом из учебника Swing по телефону Concurrency. В учебнике приведен пример Swing Worker.

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