2016-07-06 3 views
0

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

public HashMap<String, Historico> importaDadosDoExcel(){ 
    HashMap<String, Historico> mapa = new HashMap<String, Historico>(); 
    HSSFCell cell= null; 
    HSSFRow row = null; 
    Historico update = new Historico(); 
    int rowsCount = 0; 
    String[] statusStr = {"Aguardando Boleto", "Aguardando Lançamento", "Em Workflow","Liberado para Tesouraria", "Pago", "Outros"}; 
    String aux; 
    for (int i = 1; i <= rowsCount; i++) { 
     cell = row.getCell(ActvUtils.u.devolveNumColuna("D")); 
     aux = ActvUtils.u.devolveCampoLido(cell); 
     if (Arrays.asList(statusStr).contains(aux)) { 
      update.setStatus(aux); 
     }else{ 
      //Here, I would like the frame was called (passing as a parameter the value read in the cell) to which the user then chooses the best option, then, that choice was setted in the object. 
      Runnable runnable = new EscolheStatus(aux); 
      Thread thread = new Thread(runnable); 
      thread.start(); 
      //Here, I would like to read the option that the user chose on a string, some like: 
      // String str = runnable.getStatus(); 
     } 
    } 
    return mapa;  
} 

И теперь мой класс кадров:

public class EscolheStatus extends JFrame implements ActionListener,Runnable{ 


private String[] statusStr = {"Aguardando Boleto", "Aguardando Lançamento", "Em Workflow","Liberado para Tesouraria", "Pago", "Outros"}; 

private JRadioButton boleto; 
private JRadioButton lancamento; 
private JRadioButton workflow; 
private JRadioButton tesouraria; 
private JRadioButton pago; 
private JRadioButton outros; 

private String status; 
private String statusEncontrado; 

public EscolheStatus(String statusEncontrado){ 

    this.statusEncontrado = statusEncontrado; 

    boleto = new JRadioButton(statusStr[0]); 
    boleto.addActionListener(this); 

    lancamento = new JRadioButton(statusStr[1]); 
    lancamento.addActionListener(this); 

    workflow = new JRadioButton(statusStr[2]); 
    workflow.addActionListener(this); 

    tesouraria = new JRadioButton(statusStr[3]); 
    tesouraria.addActionListener(this); 

    pago = new JRadioButton(statusStr[4]); 
    pago.addActionListener(this); 

    outros = new JRadioButton(statusStr[5]); 
    outros.addActionListener(this); 

    ButtonGroup group = new ButtonGroup(); 
    group.add(boleto); 
    group.add(lancamento); 
    group.add(workflow); 
    group.add(tesouraria); 
    group.add(pago); 
    group.add(outros); 

    JPanel radioPanel = new JPanel(); 
    radioPanel.setLayout(new GridLayout(6, 1)); 
    radioPanel.add(boleto); 
    radioPanel.add(lancamento); 
    radioPanel.add(workflow); 
    radioPanel.add(tesouraria); 
    radioPanel.add(pago); 
    radioPanel.add(outros); 

    radioPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Status '" + statusEncontrado + "' não reconhecido. Escolha:" )); 
    setContentPane(radioPanel); 
    pack(); 
    this.setSize(350, 200); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.setLocationRelativeTo(null); 
    this.setVisible(true); 
    teste(); 

} 

@Override 
public void actionPerformed(ActionEvent ev) { 
    Object opcao = ev.getSource(); 

    if(opcao.equals(boleto)){ 
     status = statusStr[0]; 
    }else if(opcao.equals(lancamento)){ 
     status = statusStr[1]; 
    }else if(opcao.equals(workflow)){ 
     status = statusStr[2]; 
    }else if(opcao.equals(tesouraria)){ 
     status = statusStr[3]; 
    }else if(opcao.equals(pago)){ 
     status = statusStr[4]; 
    }else if(opcao.equals(outros)){ 
     status = statusStr[5]; 
    } 

    this.dispose(); 
} 

public String getStatus() { 
    return status; 
} 

public void setStatus(String status) { 
    this.status = status; 
} 

@Override 
public void run() { 
    new EscolheStatus(statusEncontrado); 

} 

}

+0

Использовать 'Thread.join'? – Mena

+0

Посмотрите методы 'wait()' и 'notify()'. В основном вы используете 'wait()' сообщать потоку, чтобы дождаться некоторых «событий» и 'notify()', чтобы сообщить thead, что произошло событие. Основной поток может выглядеть так: EDT запускает рабочий поток, рабочий поток читает excel, и когда требуется взаимодействие с пользователем, он открывает диалоговое окно (которое затем обрабатывается EDT) и ожидает, что диалог будет закрыт. – Thomas

+4

Другим вариантом, не использующим потоки, будет ['JOptionPane'] (https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html). – MasterBlaster

ответ

0

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

Thread worker = new Thread(new Runnable() {  
    @Override 
    public void run() { 
    long start = System.currentTimeMillis(); 

    while((System.currentTimeMillis() - start) < 10000) {   
     System.out.println("opening dialog"); 
     String result = JOptionPane.showInputDialog("Tell me something!"); 
     System.out.println("user entered: " + result); 
    }   

    System.out.println("finished"); 
    } 
}); 

worker.run(); 

Это откроет диалоговое окно и дождитесь ввода снова и снова, пока поток не будет продолжаться не менее 10 секунд.

Вы должны уметь адаптировать это к вашим потребностям.

Конечно, если несколько (рабочий) потоки должны общаться, вы можете использовать Thread.join() ждать другой поток, чтобы закончить или wait() и notify(), если оба потока должны работать параллельно и один просто должны закончить какую-то задачу и затем продолжить.

Редактировать: // String str = runnable.getStatus(); подразумевает, что вы хотите получить некоторую информацию о продолжающейся потоке. В этом случае вы можете использовать общий объект для записи и чтения (может потребоваться некоторая синхронизация).

+1

Для достоверных результатов эта строка кода 'String result = JOptionPane.showInputDialog (« Скажите мне что-нибудь! »);' Должна быть вызвана в потоке Dispatch Event. –

+0

@AndrewThompson, вы, вероятно, правы. Я долго не качался, хотя так, как бы ты это сделал? И если я не ошибаюсь, вам придется использовать wait/notify для синхронизации потоков, верно? – Thomas

+0

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

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