I'm using a JProgressBar
on my Swing
gui:
When I minimize the window while it's updating with progressBar.setValue()
it will squeeze like this:
Note that resizing or similar doesn't fix it.
Why does it happen and how to prevent it? What causes it? I want the progressbar to stay the same size like in the first image.
I'm using the GridBagLayout
.
Code to reproduce:
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.JProgressBar;
import java.awt.GridBagConstraints;
import javax.swing.JButton;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
@SuppressWarnings("serial")
public class ProgressBarSqueezeFixedExample extends JFrame
{
public ProgressBarSqueezeFixedExample()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 500);
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] { 0, 0, 0 };
gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 0 };
gridBagLayout.columnWeights = new double[] { 1.0, 0.0, Double.MIN_VALUE };
gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 1.0,
Double.MIN_VALUE };
getContentPane().setLayout(gridBagLayout);
JProgressBar progressBar = new JProgressBar();
JTextArea textArea = new JTextArea();
JButton btnRun = new JButton("Run");
setPreferredSize(new Dimension(200, 200));
btnRun.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
SwingWorker<String, String> worker = new SwingWorker<String, String>()
{
@Override
protected String doInBackground() throws Exception
{
for (int i = 0; i < 10001; i++)
{
try
{
Thread.sleep(1);
} catch (InterruptedException e)
{
e.printStackTrace();
}
progressBar.setValue(i);
progressBar.setString(i + " %");
textArea.append(i + System.lineSeparator());
}
return null;
}
};
worker.execute();
}
});
GridBagConstraints gbc_btnRun = new GridBagConstraints();
gbc_btnRun.insets = new Insets(0, 0, 5, 5);
gbc_btnRun.gridx = 0;
gbc_btnRun.gridy = 0;
getContentPane().add(btnRun, gbc_btnRun);
JLabel lblProgress = new JLabel("Progress");
GridBagConstraints gbc_lblProgress = new GridBagConstraints();
gbc_lblProgress.insets = new Insets(0, 0, 5, 5);
gbc_lblProgress.gridx = 0;
gbc_lblProgress.gridy = 1;
getContentPane().add(lblProgress, gbc_lblProgress);
progressBar.setMaximum(10000);
progressBar.setStringPainted(true);
progressBar.setMinimumSize(progressBar.getPreferredSize()); // Fixes squeezing issues
GridBagConstraints gbc_progressBar = new GridBagConstraints();
gbc_progressBar.insets = new Insets(0, 0, 5, 5);
gbc_progressBar.gridx = 0;
gbc_progressBar.gridy = 2;
getContentPane().add(progressBar, gbc_progressBar);
JScrollPane scrollPane = new JScrollPane();
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_progressBar.fill=GridBagConstraints.HORIZONTAL; // Alternate fix
gbc_scrollPane.gridwidth = 2;
gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_scrollPane.gridx = 0;
gbc_scrollPane.gridy = 3;
getContentPane().add(scrollPane, gbc_scrollPane);
scrollPane.setViewportView(textArea);
pack();
setVisible(true);
}
public static void main(String[] args)
{
new ProgressBarSqueezeFixedExample();
}
}
The resizing of the gui and squeezing the progressbar has to to with the textArea append() how it seems.
Use GridBagConstraints#fill property that is used when the component's display area is larger than the component's requested size. It determines whether to resize the component.
gbc_progressBar.fill=GridBagConstraints.HORIZONTAL;
Note: There is no need to create multiple instance of GridBagConstraints
. you can achieve same thing using single object as well.
Read more about How to Use GridBagLayout and have a look at the example.