I've spent a while reading and experimenting here, and come up with a few approaches, but not got any of them to work completely yet, so I would like to know what more experienced Swing programmers would do.
The main window of my application contains a custom subtype of JPanel, which is used to display an image calculated from a mathematical function. This can take some time to calculate, so while this happens I display a text message and a progress bar superimposed on the middle of the panel. I would like both the text and the progress bar to resize appropriately when the panel is resized, probably using a constant fraction of the width of the panel.
At the moment I have another JPanel subtype that contains the text and the progress bar, and I add this "progress panel" to the main panel, and set it to be visible when required. The main panel does not contain any other components, but has its own paintComponent() method to display a BufferedImage obtained from another class. There are a few problems with this as it stands:
So what would you do?
What about resizing the text. Do I need to explicitly create a new Font when the panel is resized, or is there any way to do this more automatically? -
The preferred size of JProgressBar
is specified by the UI delegate, BasicProgressBarUI
. The example below illustrates the effect of various layout managers. FlowLayout
simply uses the UIManager
default, ProgressBar.horizontalSize
, while GridLayout
and BorderLayout.CENTER
fill the available space. BoxLayout
, with flanking glue, adjusts proportionally as the frame is resized.
I am already using a
SwingWorker
Updating the GUI from the process()
method of your SwingWorker
should be safe. You can change layers or even remove components, but I'd be wary of anything overly complicated.
Addendum: Here's the relevant default.
System.out.println(UIManager.get("ProgressBar.horizontalSize"));
javax.swing.plaf.DimensionUIResource[width=146,height=12]
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
/** @see http://stackoverflow.com/questions/7256775 */
public class ProgressTest {
private static final Color border = Color.gray;
private static void display() {
JFrame f = new JFrame("ProgressTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(0, 1));
f.add(createPanel(new FlowLayout()));
f.add(createPanel(new GridLayout()));
f.add(createPanel(new BorderLayout()));
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
p.setBorder(BorderFactory.createLineBorder(border));
JProgressBar jpb = new JProgressBar();
p.add(Box.createHorizontalGlue());
p.add(jpb);
p.add(Box.createHorizontalGlue());
jpb.setIndeterminate(true);
f.add(p);
f.pack();
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static JPanel createPanel(LayoutManager layout) {
JPanel p = new JPanel();
p.setBorder(BorderFactory.createLineBorder(border));
p.setLayout(layout);
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(true);
p.add(jpb);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
display();
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With