【问题标题】:Resizing a JFrame调整 JFrame 的大小
【发布时间】:2019-05-17 09:03:58
【问题描述】:

好的,这将是相当愚蠢的 - 我正在使用 Eclipse 可视化编辑器(一个包含东西的 JFrame)制作一个 GUI,基本上在左侧有一些按钮和文本字段等,而右侧包含 4 JPanel(其中包含一些图形)。

问题是,当我在运行时调整 gui(JFrame)的大小时,里面的组件保持不变(大小明智),我希望这 4 个 JPanel 用 JFrame 调整大小,这可能吗?

【问题讨论】:

  • 发布您的代码。行为很大程度上取决于您如何将组件添加到 JFrame、您使用的布局管理器等。

标签: java


【解决方案1】:

简单的答案 - 使用布局管理,包括嵌套具有不同布局的多个面板以获得您想要的结果。您基本上有两个选择:(a) 使用布局管理器来管理组件的位置和大小,或者 (b) 全部手动完成。你真的不想做 (b)。

您可能希望从 layout manager tutorial 开始。

使用基于表格的布局可以使布局明显比使用 Java 分发的标准布局管理器更容易;有很多是免费的。我的地址是tech.dolhub.com

这是一个示例(来自 MatrixLayout 的帮助,但我不记得我是否真的编译过示例代码……我希望我做过一次):

+-------------------------------------------------- -----------------------------------------------+ + | + 姓名:|________________________________________________________________| | + | + 地址:|________________________________________________________________| | + | + |________________________________________________________________| | + | + |________________________________________________________________| | + | + 城市:|____________________|状态 |__|邮编 |_____| - |____| | + | + 电话:|___|-|___|-|____| | + | + 备注:| | | | | + | | | | | + | | | | | + | | | | | + | | | | | + |______________________________| |______________________________| | + [左下] [右下] | + | + [ 是 ] [ 否 ] [ 中止 ] | + | +-------------------------------------------------- -----------------------------------------------+
private void createContent(Container main){
    String[]                            rows,cols;                                  // row/column specification arrays

    JPanel                              phnpnl,cszpnl,btnpnl;                       // special nested panels

    // create components here...

    // CREATE MAIN PANEL WITH DESIRED ROWS AND COLUMNS
    rows=MatrixLayout.arrayOf(10,"Size=Pref CellAlign=Middle CellInsets=5,0");   // standard row spec
    rows[6]                     ="Size=100% CellAlign=Top    CellInsets=5,0";    // note: row 7 ([6] is index)
    rows[7]                     ="Size=Pref CellAlign=Top    CellInsets=5,0";    // note: row 8 ([7] is index)
    rows[8]                     ="Size=Pref CellAlign=Top    CellInsets=5,0";    // note: row 9 ([8] is index)
    cols=MatrixLayout.arrayOf(3 ,"size=Pref CellAlign=Right  CellInsets=5,0");   // standard column spec
    cols[1]                     ="Size=50%  CellAlign=Left   CellInsets=5,0";    // note: col 2 ([1] is index)
    cols[2]                     ="Size=50%  CellAlign=Left   CellInsets=5,0";    // note: col 3 ([2] is index)
    con.setLayout(new MatrixLayout(rows,cols,"Row=Cur Col=Next"));

    // CREATE SPECIAL NESTED PANELS
    phnpnl=MatrixLayout.singleRowBar(5,false,new DctComponent[]{phnPart1,phnPart2,phnPart3                                   });
    cszpnl=MatrixLayout.singleRowBar(5,1    ,new DctComponent[]{city,createLabel("State"),state,createLabel("Zip"),zip,zipext});
    btnpnl=MatrixLayout.singleRowBar(5,true ,new DctComponent[]{yes,no,cancel                                                });
    phnpnl.setName("PhonePanel");
    cszpnl.setName("CityStateZipPanel");
    btnpnl.setName("ButtonPanel");

    // ADD COMPONENTS TO MAIN PANEL
    con.add(createLabel(   "Name :"),"row=Next col=1"); con.add(name    ,"               hAlign=Fill  hSpan=2                               ");
    con.add(createLabel("Address :"),"row=Next col=1"); con.add(address1,"               hAlign=Fill  hSpan=2                               ");
                                                        con.add(address2,"Row=Next Col=2 hAlign=Fill  hSpan=2                               ");
                                                        con.add(address3,"Row=Next Col=2 hAlign=Fill  hSpan=2                               ");
    con.add(createLabel(   "City :"),"row=Next col=1"); con.add(cszpnl  ,"                            hSpan=2                               ");
    con.add(createLabel(  "Phone :"),"row=Next col=1"); con.add(phnpnl  ,"                            hSpan=2                               ");
    con.add(createLabel(  "Notes :"),"row=Next col=1"); con.add(notes1  ,"Row=Cur  Col=2 hAlign=Fill          vAlign=Fill                   ");
                                                        con.add(notes2  ,"Row=Cur        hAlign=Fill          vAlign=Fill                   ");
                                                        con.add(notes3  ,"Row=Next Col=2 hAlign=Left                      hGroup=NoteButtons");
                                                        con.add(notes4  ,"Row=Cur        hAlign=Right                     hGroup=NoteButtons");
    con.add(btnpnl                  ,"row=Next col=1 hAlign=Right hSpan=3");
    main.setBorder(new DctEmptyBorder(10));
    main.setBackground(SystemColor.window);
    }

【讨论】:

  • 我知道这听起来很愚蠢,但我没有使用布局管理器(因为它对我来说更容易),我在想有没有其他方法可以将这些 JPanel 链接到 JFrame(我认为当我用 C++ 编码时,Qt 中有类似的东西,我真的很喜欢)。
  • 布局管理是(有效)实现这一目标的方法;但这是一种不同于将东西附加到框架边缘的方法(几年前我写了一个布局管理器以这种方式进行布局,但后来转向基于表格的布局,因为它既简单又强大)。
  • zenzen,您的问题是您没有使用布局管理器。你不是在编写 C++ 代码。
【解决方案2】:

这取决于您如何将组件添加到框架中,以及您使用的布局管理器。在本例中,四个按钮将随窗口调整大小。

JFrame frame = new JFrame();
Container cp = frame.getContentPane();
cp.setLayout(new GridLayout(2, 2));
cp.add(new JButton("one"));
cp.add(new JButton("two"));
cp.add(new JButton("three"));
cp.add(new JButton("four"));
frame.pack();
frame.setVisible(true);

但是,您可以使用许多不同的布局管理器。 read this.

【讨论】:

    【解决方案3】:

    好的,是的,我知道我应该使用布局管理器等,但我仍然选择使用 Eclipse 可视化编辑器(它没有所有的布局管理器)来构建它,因为我没有太多时间对于这个项目,我认为这样会更快。

    基本上,这个屏幕显示了程序的外观 - 左侧的一些随机输入/按钮(暂时添加了随机的)和右侧的 4 个 JPanel - 它们对我来说非常重要。

    screen http://img130.imageshack.us/img130/5282/screenmy.png

    【讨论】:

    • 1.除非是答案,否则不要发布答案,这不是论坛。如果您认为您有更多信息要分享,请编辑您的问题。 2.使用布局管理器。这是唯一的方法。
    【解决方案4】:

    好吧,如果没有布局管理器,工作可能会很糟糕,但如果你想要的话......我们开始吧。

    1. 在您的框架中添加ComponentListener 以监听其大小调整,您可以在其中获取调整大小后的窗口大小。

    喜欢:

    frame.addComponentListener(new ComponentListener() {
    
        @Override
        public void componentShown(ComponentEvent e) {
    
        }
    
        @Override
        public void componentResized(ComponentEvent e) {
            if (e.getSource() instanceof JFrame) {
                  JFrame frame = (JFrame)(e.getSource());
                  frame.repaintElements(frame.getWidth(), frame.getHeight());
            }
        }
    
        @Override
        public void componentMoved(ComponentEvent e) {
    
        }
    
        @Override
        public void componentHidden(ComponentEvent e) {
    
        }
    });
    
      1234563 .
    1. repaintElements(int x, int y) 中,实现您的逻辑以更改每个元素的位置和大小。我使用setBound(int x, int y, int w, int h)xy 确定元素左上角相对于其容器的位置,wh 确定其大小。

    毕竟我让它在我的项目中工作,但这一切都很乏味。想一想:

    我上面有一个长标签,下面是一个表格,然后是表格下面的另一个面板,最后在右下角有一个退出按钮。

    首先是标题标签。我希望它水平扩展而不是垂直扩展,所以在我的repaintElements() 中我将其设置为:

    label1.setBounds(5, 0, x-5, 30);
    

    所以每次窗口改变大小时,标签位于最左边 5 像素,最顶部 0 像素,x-5 宽度像素(为边框留出一些空间)并且始终为 30 像素高度。

    现在我有了包含JTableJScrollPane。我希望它与窗口一起展开,所以:

    table.setBounds(5, 30, x-15, y-30-60-5);
    

    因为垂直我必须为上面的标签(30像素)和下面的面板(60像素)和下面的按钮(5像素)留出空间,而这个表格的位置由标签的高度和宽度决定以上(5 和 30,如果没有边界......)。桌子有一个垂直滚动,所以我也必须为它留出空间(所以x-15 而不是x-5。天哪。)

    然后是下面的另一个面板。如果窗口扩大,我希望这个面板也水平扩大,但不是垂直扩大,所以:

    panel.setBounds(5, y-30-60-5+30, x-10, 60); //the y value is "y coordinate of the element above" + "width of the element above"
    

    最后是按钮。我决定不增加它的大小,而是让它留在角落里,所以:

    button.setBounds(x-20, y-10, 15, 5); //the button is 15*5 pixels. extra space is for border.
    

    容易吗?看起来是这样,但你需要大量的测试......如果边界的大小发生变化,另一个地狱般的测试......实际上你把时间浪费在一些琐碎的事情上,很快你就会感到无聊。因此,请使用布局管理器。

    【讨论】:

      【解决方案5】:

      使用布局管理器。如果你不使用它,你必须自己调整它的大小(包括每次设置新位置)

      LayoutManagers 似乎有问题,实际上确实存在问题。

      在 Java 1.6 中添加了 GroupLayout 管理器,我认为它非常有用且足够简单。

      布局管理器的威力在与其他人一起使用时被释放。这是A Visual Guide to Layout Managers

      如果您发布应用程序的屏幕截图,我很确定我们可以提出一个您可以使用的基本布局。

      【讨论】:

        猜你喜欢
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多