Java JPanels don';t完全伸展以占据可用空间
我有一个面板,我将几个小面板并排放置,大小和颜色不同,它们应该占据整个父面板(水平) 为此,我使用BorderLayout(用于父面板)和BoxLayout(用于放置所有迷你面板的子面板)(请参见下面的代码)。它在调整大小和所有方面都能正常工作和工作。但是,随着迷你面板数量的增加,会出现一种奇怪的行为:在父面板的末尾会出现空白 我想我发现这是布局管理器中的一个拉伸缺陷,因为为了拉伸面板,布局管理器尝试向每个迷你面板添加一个像素。但是,当迷你面板的数量较大时,向每个面板添加一个像素将导致添加许多像素并超出父面板的大小。因此,布局管理器最终不会向任何小面板添加任何像素,从而导致空间变空 这是我的SSCCE: (试着跑一跑,打开窗户,了解问题所在)Java JPanels don';t完全伸展以占据可用空间,java,swing,awt,jpanel,border-layout,Java,Swing,Awt,Jpanel,Border Layout,我有一个面板,我将几个小面板并排放置,大小和颜色不同,它们应该占据整个父面板(水平) 为此,我使用BorderLayout(用于父面板)和BoxLayout(用于放置所有迷你面板的子面板)(请参见下面的代码)。它在调整大小和所有方面都能正常工作和工作。但是,随着迷你面板数量的增加,会出现一种奇怪的行为:在父面板的末尾会出现空白 我想我发现这是布局管理器中的一个拉伸缺陷,因为为了拉伸面板,布局管理器尝试向每个迷你面板添加一个像素。但是,当迷你面板的数量较大时,向每个面板添加一个像素将导致添加许多
package com.myPackage;
导入java.awt.*;
导入java.util.Vector;
导入javax.swing.BorderFactory;
导入javax.swing.BoxLayout;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类彩色面板扩展了JPanel
{
/*内容信息*/
私有向量划分;
私有向量颜色;
/*内容面板将要放置的面板*/
私人JPanel内容持有者;
私人最终int默认高度=20;
公共彩色面板(矢量分区、矢量颜色)
{
断言分区!=null;
assert!partitions.isEmpty();
断言颜色!=null;
断言!colors.isEmpty();
断言colors.size()==partitions.size();
this.partitions=分区;
这个。颜色=颜色;
/*设置布局管理器*/
setLayout(新的BorderLayout());
/*创建内容持有者*/
contentHolder=newjpanel();
setLayout(新的BoxLayout(contentHolder,BoxLayout.X_轴));
添加(contentHolder,BorderLayout.NORTH);
/*用彩色面板填充内容架*/
createPanels();
}
私有void createPanels()
{
断言分区!=null;
assert!partitions.isEmpty();
断言颜色!=null;
断言!colors.isEmpty();
断言colors.size()==partitions.size();
对于(int i=0;i
我如何避免这种行为?我希望我的面板占据整个容器
编辑:
迷你面板旨在(解决此问题后)具有鼠标侦听器。因此,油漆解决方案是不可避免的。我可以想到两种选择:
paintComponent(…)
方法,当窗口调整大小时,它将重新绘制区域,同时根据新的宽度信息缩放它们我曾经在为棋盘使用GridLayout时遇到过这个问题。我的解决方案是扩展GridLayout并用浮点精度计算布局。布局问题通过。。。LayoutManager:-)如果一个人不知道你想要它做什么,那么就实施你想要的行为 因此,如果core 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);
}
}
}
}
公共静态类XBoxLayout扩展了BoxLayout{
枚举策略{
没有一个
最后一个,
怀疑
}
私人战略;
公共XBoxLayout(容器目标、int轴、策略){
超级(目标、轴);
这个。策略=策略;
}
@凌驾
公共void布局容器(容器目标){
超级.布局容器(目标);
如果(Strategy.NONE==策略)返回;
Insets targetSets=target.getInsets();
int targetSize=target.getWidth()-targetSets.left-targetSets.right;
int childSum=0;
for(组件子级:target.getComponents()){
childSum+=child.getWidth();
}
如果(targetSize>childSum){
int excess=targetSize-childSum;
分配(目标、超额);
}
}
私有void分发(容器目标,整数过量){
System.out.println(“childCount/舍入超额”+target.getComponentCount()+“/”+超额);
if(Strategy.STRETCH_LAST==策略){
Component lastChild=target.getComponent(目标
.getComponentCount()-1);
lastChild.setSize(lastChild.getWidth()+多余,
lastChild.getHeight());
}否则{
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);
}
}
}
}