tl;博士:我想做第二张图片中的内容(忽略红线)
我理解GroupLayout是如何工作的,但我无法弄清楚这一点,或者它是否可能。我最初有这个代码:
#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))))
产生了这个:
但是,我想在进度条的开头和结尾对齐2个顶部标签,在进度条的开始,中间和结尾对齐3个底部标签,如下所示(mspainted):
我的第一个方法是尝试将组件拆分为我用上面的线组成的并行组。我在进度条的两侧放置了支柱,将4个末端标签对齐,并将中心标签与进度条本身对齐:
#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))
然而,正如我所料,这迫使进度条挤入前2个标签之间的水平空间,如下所示:
最后,我想要摆脱struts,并将进度条添加到三个单独的并行组中:将LEADING
与两个左侧标签对齐,CENTER
与中间标签对齐,{{{ 1}}使用正确的标签:
TRAILING
然而,Swing明显忽略了进度条的第二和第三次提及,我最终得到了这个:
我认为我在这方面做得非常不错,而且我很有想法。有没有办法让组件跨越多个并行组?
答案 0 :(得分:3)
根据您的要求,我宁愿使用GridBagLayout
。它有点复杂,但我写了一段代码,可以做你想要的。
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();
}
结果如下:
答案 1 :(得分:3)
你会如何筑巢?
如下图所示。
似乎很快就会变得过于复杂。
这取决于要求。
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
/** @see http://stackoverflow.com/questions/7279799 */
public class NestedLayout extends Box {
private String s1 = "Started at: 2011-09-12 15:33:38";
private String s2 = "Last updated: 2011-09-12 15:33:44";
private String s3 = "File copied:2/10";
private String s4 = "Bytes copied: 234/1000";
private String s5 = "ETC: 2011-09-02 15:34:02";
private JProgressBar pb = new JProgressBar();
public NestedLayout(int axis) {
super(axis);
JPanel top = new JPanel(new GridLayout());
top.add(new JLabel(s1, JLabel.LEFT));
top.add(new JLabel(s2, JLabel.RIGHT));
JPanel mid = new JPanel(new GridLayout());
pb.setMaximum(100);
pb.setStringPainted(true);
pb.setString("23%");
pb.setValue(23);
mid.add(pb);
JPanel bot = new JPanel(new GridLayout());
bot.add(new JLabel(s3, JLabel.LEFT));
bot.add(new JLabel(s4, JLabel.CENTER));
bot.add(new JLabel(s5, JLabel.RIGHT));
Box east = new Box(BoxLayout.Y_AXIS);
east.add(Box.createVerticalGlue());
east.add(new JButton("Clear"));
east.add(Box.createVerticalGlue());
JPanel center = new JPanel(new GridLayout(0, 1));
center.add(top);
center.add(mid);
center.add(bot);
this.add(center);
this.add(east);
}
private void display() {
JFrame f = new JFrame("NestedLayout");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new NestedLayout(BoxLayout.X_AXIS).display();
}
});
}
}
答案 2 :(得分:2)
显然已经太晚了,但是当我寻找类似的东西时,我发现了这个问题,所以其他人可能会觉得这个答案很有用。
这个答案实际上使用了GroupLayout。这里我唯一认为是黑客攻击的是设置滚动条的首选大小(如果你把它拿出来,标签会重叠。)
它比您可能怀疑的更简单:
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class LayoutTest implements Runnable {
private JLabel startTimeLabel = new JLabel("start time");
private JLabel lastUpdatedLabel = new JLabel("last updated");
private JLabel fileProgLabel = new JLabel("file progress");
private JLabel sizeProgLabel = new JLabel("size progress");
private JLabel etcLabel = new JLabel("etc");
private JButton clearBtn = new JButton("Clear");
private JProgressBar progressBar = new JProgressBar(new DefaultBoundedRangeModel(27, 0, 0, 100));
public static void main(String[] args) {
SwingUtilities.invokeLater(new LayoutTest());
}
@Override
public void run() {
progressBar.setStringPainted(true);
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateContainerGaps(true);
layout.setAutoCreateGaps(true);
panel.setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(progressBar, GroupLayout.DEFAULT_SIZE, 500, GroupLayout.DEFAULT_SIZE)
.addComponent(startTimeLabel, GroupLayout.Alignment.LEADING)
.addComponent(fileProgLabel, GroupLayout.Alignment.LEADING)
.addComponent(sizeProgLabel, GroupLayout.Alignment.CENTER)
.addComponent(lastUpdatedLabel, GroupLayout.Alignment.TRAILING)
.addComponent(etcLabel, GroupLayout.Alignment.TRAILING))
.addComponent(clearBtn));
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(startTimeLabel)
.addComponent(lastUpdatedLabel))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(progressBar)
.addComponent(clearBtn))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(fileProgLabel)
.addComponent(sizeProgLabel)
.addComponent(etcLabel)));
JFrame frame = new JFrame("Layout Test");
frame.setContentPane(panel);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
可能有一种方法可以为LEADING和TRAILING组件对使用并行组,但是当我尝试这样做时,布局完全重新排列。
有时GroupLayout问题的解决方案是在执行水平布局时忽略垂直布局,在执行垂直布局时忽略水平布局。将布局展平为单个维度(重新排列彼此相邻的相似行和列有助于)并编写布局以匹配头部中的1D图片。
我特别建议不要使用GridBagLayout,方框等,因为以跨平台的方式在组件之间获得正确的间距是一场噩梦。