В следующем классе рабочий создается внутри диалога. Во время выполнения работника он обновляет текст, поданный в диалоговом окне.Почему 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);
}
}
В качестве побочного примечания ваши вызовы 'setStatusMessage' в' doInBackground' являются ilegal, поскольку они в конечном итоге изменяют GUI из-за пределов EDT. (propertyChange выполняется в том же потоке, где вызывается firePropertyChange). Возможно, вы захотите использовать механизмы 'publish' и' process', или вызовите 'invokeLater'. – DSquare
@DSquare, очевидно, говорится в руководстве, что уведомления о свойствах выполняются на EDT автоматически. Может быть, я понял неправильно ... –
@DSquare да, это делается в классе SwingWorker.SwingWorkerPropertyChangeSuppor', который автоматически отправляется в EDT. –