Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否使用BoxLayout将面板之间的间距强制为0?_Java_Swing_Layout Manager_Java 2d_Boxlayout - Fatal编程技术网

Java 是否使用BoxLayout将面板之间的间距强制为0?

Java 是否使用BoxLayout将面板之间的间距强制为0?,java,swing,layout-manager,java-2d,boxlayout,Java,Swing,Layout Manager,Java 2d,Boxlayout,目前,作为我正在进行的一个项目的一部分,我正在实现一个组件,该组件可用于可视化位的排列(作为加密算法的一部分)。我这样做是通过创建两行“针”,并通过在尖端之间画线连接它们,在它们之间创建一种网络 这其中的一个重要部分是,我正在使用这个可视化本身以及其他可视化的一部分(例如,我可能希望包括S盒),因此我需要能够打开和关闭引脚。我的解决方案是使用JPanels将多行插针放入页眉和页脚面板中,使其不可见 我将它们垂直放置在一个BoxLayout中,但即使在页眉上方和页脚下方添加胶水,它们之间也会留有空

目前,作为我正在进行的一个项目的一部分,我正在实现一个组件,该组件可用于可视化位的排列(作为加密算法的一部分)。我这样做是通过创建两行“针”,并通过在尖端之间画线连接它们,在它们之间创建一种网络

这其中的一个重要部分是,我正在使用这个可视化本身以及其他可视化的一部分(例如,我可能希望包括S盒),因此我需要能够打开和关闭引脚。我的解决方案是使用
JPanel
s将多行插针放入页眉和页脚面板中,使其不可见

我将它们垂直放置在一个
BoxLayout
中,但即使在页眉上方和页脚下方添加胶水,它们之间也会留有空间

我的示例在初始化时如下所示:

当我调整它的大小时,它们会聚集在一起,但仍然只接触一面:

我猜这是一个愚蠢的错误,从组件大小和布局的角度将我的用户空间转换为设备空间,但就我的一生而言,我找不到它。这是我的代码,尽管我为混乱道歉:

import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Ellipse2D;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PermutationWeb extends JPanel
{
    private static enum EndPanelType
    {
        HEADER, FOOTER
    }

    private final JPanel header;
    private final JPanel mainPanel;
    private final JPanel footer;

    private double  widthFactor;
    private double  heightFactor;
    private int     widthMax;
    private int     heightMax;
    private int[]   indexMappings;
    private Point2D.Double[] endpoints;
    private Line2D.Double[]  drawingLines;

    public PermutationWeb(int indices, boolean endPanelsOn)
    {
        super();

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        widthMax  = (indices + 1)*2;
        heightMax = (int)Math.round(widthMax*(3.0/17.0));
        widthFactor  = 1;
        heightFactor = 1;

        endpoints    = new Point2D.Double[indices * 2];
        drawingLines = new Line2D.Double[indices];

        for(int i=0; i<indices; i++)
        {
            endpoints[i]         = new Point2D.Double(i*2+2, 0);
            endpoints[i+indices] = new Point2D.Double(i*2+2, heightMax);
            drawingLines[i] = new Line2D.Double();
        }

        header    = new WebEndPanel(EndPanelType.HEADER);
        mainPanel = new WebMainPanel();
        footer    = new WebEndPanel(EndPanelType.FOOTER);

        add(Box.createVerticalGlue());
        add(header);
        add(mainPanel);
        add(footer);
        add(Box.createVerticalGlue());

        setEndPanelsOn(endPanelsOn);
    }

    public Point2D getEndpoint(int index)
    {
        return endpoints[index];
    }

    public void updateMappings(int[] mappings)
    {
        this.indexMappings = mappings;

        for(int i=0; i<indexMappings.length; i++)
        {
            drawingLines[i].setLine(endpoints[i], endpoints[indexMappings.length + indexMappings[i]]);
        }

        //paint();
    }

    public void setEndPanelsOn(boolean endPanelsOn)
    {
        header.setVisible(endPanelsOn);
        footer.setVisible(endPanelsOn);
    }

    @Override
    public Dimension getMaximumSize()
    {
        int height = mainPanel.getHeight();
        if(header.isVisible())
        {
            height += (header.getHeight() * 2);
        }

        int width = mainPanel.getWidth();

        return new Dimension(width, height);
    }

    @Override
    public Dimension getPreferredSize()
    {
        return getMaximumSize();
    }

    public static void main(String[] args)
    {
        JFrame jf = new JFrame();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setSize(800, 600);

        int[] mappings = {0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15};

        PermutationWeb webTest = new PermutationWeb(16, true);
        jf.add(webTest);
        jf.setVisible(true);
        webTest.setVisible(true);

        webTest.updateMappings(mappings);

        System.out.printf("Header:    [%s]\nMainPanel: [%s]\nFooter:    [%s]\n",
                webTest.header.getSize().toString(),
                webTest.mainPanel.getSize().toString(),
                webTest.footer.getSize().toString());
    }


    private class WebMainPanel extends WebSubPanel
    {
        private static final double HEIGHT_RATIO = 0.25;

        @Override
        public void paintComponent(Graphics g)
        {
            Graphics2D g2 = (Graphics2D)g;
            super.paintComponent(g2);

            scaleTo(getSize());
            g2.scale(widthFactor, widthFactor);
            g2.setStroke(new BasicStroke((float)(2.0/widthFactor)));

            for(Line2D line: drawingLines)
            {
                g2.draw(line);
            }
        }

        @Override
        public Dimension getMaximumSize()
        {
            return new Dimension(MAX_WIDTH_PX, (int)(MAX_WIDTH_PX*HEIGHT_RATIO));
        }
    }

    private class WebEndPanel extends WebSubPanel
    {
        private static final double HEIGHT_RATIO = 0.125;
        private static final double PIN_RADIUS = 0.5;

        private final EndPanelType endType;
        private Line2D.Double[]    edgeLines;
        private Ellipse2D.Double[] pinHeads;

        public WebEndPanel(EndPanelType endType)
        {
            super();
            this.endType = endType;
            this.edgeLines = new Line2D.Double[endpoints.length/2];
            this.pinHeads  = new Ellipse2D.Double[endpoints.length/2];

            for(int i=0; i<edgeLines.length; i++)
            {
                Point2D pointA;
                Point2D pointB;


                if(EndPanelType.HEADER.equals(this.endType))
                {
                    pointA = new Point2D.Double(i*2+2, 4);
                    pointB = new Point2D.Double(i*2+2, 2);

                    pinHeads[i]  = new Ellipse2D.Double(
                            pointB.getX()-PIN_RADIUS,
                            pointB.getY()-PIN_RADIUS*2,
                            PIN_RADIUS*2,
                            PIN_RADIUS*2);
                }
                else // FOOTER
                {
                    pointA = new Point2D.Double(i*2+2, 0);
                    pointB = new Point2D.Double(i*2+2, 2);

                    pinHeads[i]  = new Ellipse2D.Double(
                            pointB.getX()-PIN_RADIUS,
                            3-PIN_RADIUS*2,
                            PIN_RADIUS*2,
                            PIN_RADIUS*2);
                }

                edgeLines[i] = new Line2D.Double(pointA, pointB);
            }
        }

        @Override
        public Dimension getMaximumSize()
        {
            return new Dimension(MAX_WIDTH_PX, (int)(MAX_WIDTH_PX*HEIGHT_RATIO));
        }

        @Override
        public void paintComponent(Graphics g)
        {
            Graphics2D g2 = (Graphics2D)g;
            super.paintComponent(g2);

            scaleTo(getSize());
            g2.scale(widthFactor, widthFactor);
            g2.setStroke(new BasicStroke((float)(2.0/widthFactor)));

            for(Line2D line: edgeLines)
            {
                g2.draw(line);
            }

            for(Ellipse2D pin: pinHeads)
            {
                g2.draw(pin);
            }
        }
    }

    private abstract class WebSubPanel extends JPanel
    {
        protected static final int MAX_WIDTH_PX = 800;

        public WebSubPanel()
        {
            super();
            setBorder(null);
            setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        }

        public void scaleTo(Dimension d)
        {
            widthFactor  = d.getWidth()  / (double)widthMax;
            heightFactor = d.getHeight() / (double)heightMax;
        }

        @Override
        public Dimension getPreferredSize()
        {
            return getMaximumSize();
        }        
    }
}
import java.awt.BasicStroke;
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.geom.Line2D;
导入java.awt.geom.Point2D;
导入java.awt.geom.Ellipse2D;
导入javax.swing.Box;
导入javax.swing.BoxLayout;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类置换Web扩展了JPanel
{
私有静态枚举EndPanelType
{
页眉、页脚
}
专用最终JPanel报头;
私人最终JPanel主面板;
私有最终JPanel页脚;
私人双因素;
私人双高度系数;
私有int-widthMax;
私人海特马克斯酒店;
私有int[]索引映射;
私有点2D。双[]端点;
专用线条2D。双[]绘制线条;
公共置换网络(整数索引,布尔ENDPOLENDSON)
{
超级();
setLayout(新的BoxLayout(这是BoxLayout.Y_轴));
最大宽度=(指数+1)*2;
heightMax=(int)数学圆(widthMax*(3.0/17.0));
宽度因子=1;
高度系数=1;
端点=新点2d.Double[索引*2];
drawingLines=新线2D.双[索引];

对于(int i=0;iA
BoxLayout
,如果空间可用,将调整组件的大小,使其达到最大尺寸

因此,您首先需要实现组件的
getPreferredSize()
方法,以便可以按正常大小打包组件

然后,如果它能够增长(并且您的自定义绘图支持这一点),您可以覆盖
getMaximumSize()
方法以返回大小


这幅画需要以面板的实际尺寸为基础,如果你希望它与其他面板相邻。

我必须检查代码多一点,但乍一看,看起来你应该考虑把所有这些画成一个单一的面板。你仍然可以达到所有想要的效果,并且不依赖于布局管理器。(对于“普通图形用户界面”来说,这很好,但对于定制绘画来说,这可能非常脆弱)@Marco13我肯定会选择一种更简单的解决方案,即一次绘制所有图形,但该项目需要根据用户的定义按需绘制不同自定义形状的不同配置,因此,如果我没有在这里面对这个问题,我以后将不可避免地面对它。我知道BoxLayout尊重最大尺寸,但您的答案是这让我尝试了最终解决问题的方法:我重写getMaximumSize(),使其宽度始终为MAX_值,高度由我为首选尺寸的高度设置的值决定,然后使用与实际宽度的比率来限制首选高度。