tl;dr: I want to do what's in the second picture (ignore the red lines)
I understand how GroupLayout works, but I can't figure this out, or whether it's even possible. I initially had this code:
#Horizontal layout is a parallel group containing 3 sequences of components
layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) #everything else to the right
.addGroup(layout.createSequentialGroup() #row 1
.addComponent(startTimeLabel)
.addComponent(self.lastUpdatedLabel))
.addGroup(layout.createSequentialGroup() #row 2
.addComponent(self.progressBar)
.addComponent(self.clearBtn))
.addGroup(layout.createSequentialGroup() #row 3
.addComponent(self.fileProgLabel)
.addComponent(self.sizeProgLabel)
.addComponent(self.ETCLabel))))
which produced this:
However, I want to align the 2 top labels at the start and end of the progress bar, and the 3 bottom labels at the start, middle, and end of the progress bar, like this (mspainted):
My first approach at this was to try to split the components into the parallel groups I've made with the lines above. I put struts either side of the progress bar, aligning the 4 end labels to those, and aligned the center label to the progress bar itself:
#Horizontal layout is a sequence of 3 parallel groups of components, and an end component
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) #starttime, strut, filesprog
.addComponent(startTimeLabel)
.addComponent(progLeft) #invisible, just for gluing things to
.addComponent(self.fileProgLabel))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) #progress bar, sizeprog
.addComponent(self.progressBar)
.addComponent(self.sizeProgLabel))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) #updatetime, strut, ETC
.addComponent(self.lastUpdatedLabel)
.addComponent(progRight) #invisible, just for gluing things to
.addComponent(self.ETCLabel))
.addComponent(self.clearBtn))
However, as I expected, this forced the progress bar to squeeze into the horizontal space between the top 2 labels, like this:
Finally, I thought of getting rid of the struts, and adding the progress bar to three separate parallel groups: aligned LEADING
with the two left labels, CENTER
with the middle label, and TRAILING
with the right label:
#Horizontal layout is a sequence of 4 parallel groups of components
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) #starttime, progleft, filesprog
.addComponent(startTimeLabel)
.addComponent(self.progressBar)
.addComponent(self.fileProgLabel))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) #progmid, sizeprog
.addComponent(self.progressBar)
.addComponent(self.sizeProgLabel))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) #updatetime, progright, ETC
.addComponent(self.lastUpdatedLabel)
.addComponent(self.progressBar)
.addComponent(self.ETCLabel))
.addComponent(self.clearBtn))
However, Swing clearly ignores the second and third mentions of the progress bar, and I end up with this:
I reckon I've had a pretty decent go at this, and I'm well and truly out of ideas. Is there any way to make a component span multiple parallel groups?
Given your requirements, I would rather use a GridBagLayout
. It's a bit more complex but I wrote a piece of code that does what you want.
class T extends JFrame {
public T() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
String s1 = "Started at: 2011-09-12 15:33:38";
String s2 = "Last updated: 2011-09-12 15:33:44";
String s3 = "File copied:2/10";
String s4 = "Bytes copied: 234/1000";
String s5 = "ETC: 2011-09-02 15:34:02";
JProgressBar progressBar = new JProgressBar();
progressBar.setMinimum(100);
progressBar.setStringPainted(true);
progressBar.setString("23%");
progressBar.setValue(23);
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
c.insets = new Insets(5, 5, 5, 5);
add(new JLabel(s1), c);
c.gridx = 2;
add(new JLabel(s2, JLabel.RIGHT), c);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
add(progressBar, c);
c.gridx = 3;
add(new JButton("Clear"), c);
c.gridx = 0;
c.gridy = 2;
add(new JLabel(s3), c);
c.gridx = 0;
add(new JLabel(s4, JLabel.CENTER), c);
c.gridx = 2;
add(new JLabel(s5, JLabel.RIGHT), c);
setSize(600, 300);
setVisible(true);
}
public static void main(String[] args) {
new T();
}
Here is the result: