Ano*_*oyz 6 java swing awt jpanel border-layout
我有一个面板,我可以并排放置几个不同尺寸和颜色的迷你面板,它们应该占据整个父面板(水平).
为此我使用BorderLayout(用于父面板),BoxLayout用于子面板,我放置所有迷你面板(参见下面的代码).它可以正常工作,并且可以正常调整大小和一切.但是,随着迷你面板数量的增加,会出现奇怪的行为:父面板末端出现空白区域.

我想我发现这是布局管理器中的拉伸错误,因为为了拉伸面板,布局管理器尝试向每个迷你面板添加一个像素.但是,当迷你面板的数量很大时,向每个面板添加一个像素将导致添加许多像素并超出父级的大小.因此,布局管理器最终不会向任何迷你面板添加任何像素,从而导致空白空间.
这是我的SSCCE :(尝试运行,拉伸窗口,以了解问题)
package com.myPackage;
import java.awt.*;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ColoredPanels extends JPanel
{
/* Content information. */
private Vector<Integer> partitions;
private Vector<Color> colors;
/* Panel where the content panels will go. */
private JPanel contentHolder;
private final int defaultHeight = 20;
public ColoredPanels(Vector<Integer> partitions, Vector<Color> colors)
{
assert partitions != null;
assert !partitions.isEmpty();
assert colors != null;
assert !colors.isEmpty();
assert colors.size() == partitions.size();
this.partitions = partitions;
this.colors = colors;
/* Set layout manager. */
setLayout(new BorderLayout());
/* Create the content holder. */
contentHolder = new JPanel();
contentHolder.setLayout(new BoxLayout(contentHolder, BoxLayout.X_AXIS));
this.add(contentHolder, BorderLayout.NORTH);
/* Fill content holder with colored panels. */
createPanels();
}
private void createPanels()
{
assert partitions != null;
assert !partitions.isEmpty();
assert colors != null;
assert !colors.isEmpty();
assert colors.size() == partitions.size();
for (int i = 0; i < partitions.size(); i++)
{
JPanel newPanel = new JPanel();
newPanel.setBackground(colors.get(i));
newPanel.setPreferredSize(new Dimension(partitions.get(i), defaultHeight));
newPanel.setMinimumSize(new Dimension(1, defaultHeight));
contentHolder.add(newPanel);
}
}
public static void main(String[] in)
{
Vector<Integer> sizes = new Vector<Integer>();
Vector<Color> cols = new Vector<Color>();
/* Make 100 random sizes, and use two colors. */
for (int i = 0; i < 100; i++)
{
int size = (int)Math.round(1 + Math.random() * 10);
sizes.add(size);
cols.add((i%2 == 0)? Color.red : Color.green);
}
ColoredPanels panels = new ColoredPanels(sizes, cols);
panels.setBorder(BorderFactory.createLineBorder(Color.yellow, 1));
JFrame newFrame = new JFrame();
newFrame.getContentPane().add(panels);
newFrame.pack();
newFrame.setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何避免这种行为?我希望我的面板占据整个容器.
编辑: 迷你面板旨在(一旦解决)鼠标听众.因此,涂料解决方案是不幸的.
布局问题可以通过... LayoutManagers 解决:-) 如果没有达到您想要的效果,请实现您想要的行为。
因此,如果核心 BoxLayout 只是由于舍入错误而忽略像素,请子类化并使其根据需要分配这些像素。一个非常原始的快速示例:
public static class XBoxLayout extends BoxLayout {
enum Strategy {
NONE,
STRETCH_LAST,
DISTRUBUTE
}
private Strategy strategy;
public XBoxLayout(Container target, int axis, Strategy strategy) {
super(target, axis);
this.strategy = strategy;
}
@Override
public void layoutContainer(Container target) {
super.layoutContainer(target);
if (Strategy.NONE == strategy) return;
Insets targetInsets = target.getInsets();
int targetSize = target.getWidth() - targetInsets.left - targetInsets.right;
int childSum = 0;
for (Component child : target.getComponents()) {
childSum += child.getWidth();
}
if (targetSize > childSum) {
int excess = targetSize - childSum;
distribute(target, excess);
}
}
private void distribute(Container target, int excess) {
System.out.println("childCount/rounding excess " + target.getComponentCount() + "/" + excess);
if (Strategy.STRETCH_LAST == strategy) {
Component lastChild = target.getComponent(target
.getComponentCount() - 1);
lastChild.setSize(lastChild.getWidth() + excess,
lastChild.getHeight());
} else {
int firstToDistribute = target.getComponentCount() - excess;
int summedOffset = 0;
for(int index = firstToDistribute; index < target.getComponentCount(); index++) {
Component child = target.getComponent(index);
Rectangle bounds = child.getBounds();
bounds.x += summedOffset++;
bounds.width += 1;
child.setBounds(bounds);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3362 次 |
| 最近记录: |