2014-08-01 3 views
0

В следующем классе рабочий создается внутри диалога. Во время выполнения работника он обновляет текст, поданный в диалоговом окне.Почему TextField не растет как статически, так и динамически?

К сожалению, ширина TextField не растет согласно содержанию.

Кроме того, ширина текстового поля является узкой изначально, точно для ее содержания, несмотря на то, что она настроена на рост в MigLayout.

Как исправить?

public abstract class JStatusMessageWorkerDialog<T> extends JDialog { 

    private static final long serialVersionUID = -6373593735878434741L; 

    private class Worker extends SwingWorker<T, String> { 

     private String statusMessage; 

     private Worker() { 
     } 

     public synchronized String getStatusMessage() { 
      return statusMessage; 
     } 

     public synchronized void setStatusMessage(String newValue) { 
      String oldValue = this.statusMessage; 
      this.statusMessage = newValue; 
      firePropertyChange("statusMessage", oldValue, newValue); 
     } 

     @Override 
     protected T doInBackground() throws Exception { 
      return JStatusMessageWorkerDialog.this.doInBackground(); 
     } 

     @Override 
     protected void done() { 
      JStatusMessageWorkerDialog.this.dispose(); 
     } 



    } // CorpusWorker class 

    Worker worker; 

    Icon corpusPropgressIcon = createIcon(); 

    JLabel corpusProgressIconLabel = new JLabel(corpusPropgressIcon); 

    JPanel iconPanel = new JPanel(); 
    { 
     iconPanel.setLayout(new MigLayout("fill")); 
     iconPanel.add(corpusProgressIconLabel, ""); 
    } 

    JTextField statusText = new JTextField(); 
    { 
     statusText.setEditable(false); 
     statusText.setText("text"); 
    } 


    JPanel statusPanel = new JPanel(); 
    { 
     statusPanel.setLayout(new MigLayout("fill")); 
     statusPanel.add(statusText, "growx"); 
    } 

    AbstractAction closeAction = new AbstractAction("Отмена") { 

     private static final long serialVersionUID = 1L; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      closeAction.setEnabled(false); 
      worker.cancel(true); 
     } 
    }; 

    JButton closeButton = new JButton(closeAction); 

    JPanel buttonPanel = new JPanel(); 
    { 
     buttonPanel.setLayout(new FlowLayout()); 
     buttonPanel.add(closeButton); 
    } 

    { 
     setLayout(new MigLayout("debug, fill")); 

     add(iconPanel, "split"); 
     add(statusPanel, "wrap"); 
     add(buttonPanel, "w 640px, grow"); 
    } 



    public JStatusMessageWorkerDialog() { 

     worker = createWorker(); 
     worker.addPropertyChangeListener(new PropertyChangeListener() { 

      @Override 
      public void propertyChange(PropertyChangeEvent evt) { 
       if("statusMessage".equals(evt.getPropertyName())) { 
        statusText.setText((String) evt.getNewValue()); 
        //statusText.validate(); 

        //statusPanel.invalidate(); 
        //statusPanel.doLayout(); 

        statusText.revalidate(); 
       } 

      } 
     }); 

     setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 
     setModalityType(ModalityType.APPLICATION_MODAL); 
     addComponentListener(new ComponentAdapter() { 
      @Override 
      public void componentShown(ComponentEvent e) { 
       worker.execute(); 
      } 
     }); 

     addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent e) { 
       closeAction.actionPerformed(null); 
      } 
     }); 

    } 


    protected Worker createWorker() { 
     return new Worker(); 
    } 

    protected Icon createIcon() { 
     return UIManager.getDefaults().getIcon("OptionPane.informationIcon"); 
    } 

    protected void setStatusMessage(String newValue) { 
     worker.setStatusMessage(newValue); 
    } 

    public String getStatusMessage() { 
     return worker.getStatusMessage(); 
    } 

    protected abstract T doInBackground() throws Exception; 

    public static void main(String[] args) { 
     JStatusMessageWorkerDialog<Object> dialog = new JStatusMessageWorkerDialog<Object>() { 

      @Override 
      protected Object doInBackground() throws Exception { 


       Thread.sleep(5000); 

       setStatusMessage("state 2"); 

       Thread.sleep(5000); 

       setStatusMessage("state 3"); 

       return null; 
      } 
     }; 

     dialog.pack(); 
     dialog.setLocationRelativeTo(null); 
     dialog.setVisible(true); 
    } 

} 
+0

В качестве побочного примечания ваши вызовы 'setStatusMessage' в' doInBackground' являются ilegal, поскольку они в конечном итоге изменяют GUI из-за пределов EDT. (propertyChange выполняется в том же потоке, где вызывается firePropertyChange). Возможно, вы захотите использовать механизмы 'publish' и' process', или вызовите 'invokeLater'. – DSquare

+0

@DSquare, очевидно, говорится в руководстве, что уведомления о свойствах выполняются на EDT автоматически. Может быть, я понял неправильно ... –

+0

@DSquare да, это делается в классе SwingWorker.SwingWorkerPropertyChangeSuppor', который автоматически отправляется в EDT. –

ответ

0

На данный момент у меня нет доступа к моему компьютеру, поэтому я только списываю верхнюю часть моей головы.

Во-первых, изменить первоначальный размер текстового поля, необходимо добавить параметр в JTextField конструктора, который является количество colums. Текстовое поле вычисляет свою первоначальную ширину в соответствии с числом столбцов оно имеет:

JTextField statusText = new JTextField(10); 

Сочетание grow и fill ограничения делает компонент расти, когда изменение размеров окна. Это не заставляет его расти при изменении содержимого - нужно сделать это вручную.

На мой взгляд, желательно создать текстовое поле, достаточно большое, чтобы содержал самый большой текст, вместо того чтобы его динамически изменять.

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