Resizing a JFrame

泄露秘密 提交于 2019-12-13 18:09:36

问题


Ok, this will be rather noobish - I'm making a GUI with the Eclipse Visual Editor (a JFrame with stuff in it), basically on the left side there are some buttons and textfields etc. and the right side contains 4 JPanels (with some graphics in them).

The problem is, when I resize the gui (the JFrame) during runtime the components inside stay the same (size wise) and I'd want those 4 JPanels to resize with the JFrame, is it possible?


回答1:


Simple answer - use layout management, including nesting multiple panels with different layouts to get the result you want. You've essentially got two choices: (a) use a layout manager to manage component location and sizing, or (b) do it all manually. You really don't want to do (b).

You might want to start with the layout manager tutorial.

Using a table based layout can make layout significantly easier than the standard layout managers distributed with Java; there are many available for free. Mine is at tech.dolhub.com.

Here's an example (from the help in MatrixLayout, but I don't recall if I ever actually compiled the example code... I expect I did once):

+--------------------------------------------------------------------------------+
+                                                                                |
+     Name : |________________________________________________________________|  |
+                                                                                |
+  Address : |________________________________________________________________|  |
+                                                                                |
+            |________________________________________________________________|  |
+                                                                                |
+            |________________________________________________________________|  |
+                                                                                |
+     City : |____________________| State |__| Zip |_____| - |____|              |
+                                                                                |
+    Phone : |___|-|___|-|____|                                                  |
+                                                                                |
+    Notes : |                              |  |                              |  |
+            |                              |  |                              |  |
+            |                              |  |                              |  |
+            |                              |  |                              |  |
+            |                              |  |                              |  |
+            |______________________________|  |______________________________|  |
+            [BOTTOM-LEFT]                                     [ BOTTOM-RIGHT ]  |
+                                                                                |
+                       [      Yes      ]   [      No      ]   [    Abort     ]  |
+                                                                                |
+--------------------------------------------------------------------------------+
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);
    }



回答2:


It depends on how you add your components to the frame, and what layout manager you use. in this example, the four buttons will resize with the window.

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);

you can use many different layout managers however. read this.




回答3:


Ok, yeah I know I should use a layout manager etc. but still I chose to build it with the Eclipse Visual Editor (which doesn't have all the layout managers there are) is because I don't have much time for this project and I thought it would be faster that way.

Basically this screen shows how the program should look - some random input/buttons on the left (added random ones for the time being) and the 4 JPanels on the right - they are quite important to me.

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




回答4:


Well, it can be terrible work without a Layout manager, but if you want it..... here we go.

  1. Add a ComponentListener to your frame to listen for its resizing, where you can get the size of windows after resizing.

Like:

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) {

    }
});
  1. In your JFrame class (in this case you must make it a child class of JFrame to add your own method), define a repaintElements(int w, int h) method, taking the new height and new width as arguments.

  2. In repaintElements(int x, int y), implement your logic to change the location and size of every element. I use setBound(int x, int y, int w, int h). x and y determines the location of the left top corner of an element, relative to its container, and w and h determine its size.

After all I got it to work in my project, but it's all tedious. Think about this:

I have a long label atop, and then a table below, and then another panel below the table, at last a button of exit at right down corner.

First of all, the title label atop. I want it to expand horizontally but not vertically, so in my repaintElements() I set it like:

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

so every time the windows changes size, the label is located on the 5 pixels from the very left, 0 pixels from the very top, x-5 pixels of width (to leave some space for the border) and always 30 pixels of height.

Now I have the JScrollPane containing the JTable. I want it to expand along with the window, so:

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

Because vertically I must leave space for the label above (30 pixels) and the panel below(60 pixels) and the button below(5 pixels), and the location of this table is determined by the height and width of the label above (5 and 30, if without borders...). The table has a vertical scroll so I have to leave space for it, too(so x-15 instead of x-5. Holy shit.)

And then another panel below. If the window expands, horizontally I want this panel increase too, but not vertically, so:

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"

At last, the button. I decide not to increase its size, but just let it stay in the corner, so:

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

Easy? It seems so, but you need a lot of testing........ And if the size of the border changes, another hell of testing... Actually you waste time in some trivial things and soon you get bored. So, use a Layout manager.




回答5:


Use a layout manager. If you don't use it you'll have to resize it your self ( which would include setting the new location each time )

LayoutManagers seems problematic and actually they are.

In Java 1.6 the GroupLayout manager was added and I think it is quite useful and simple enough.

The power of the layout managers is released when used in conjunctions with others. Here's a A Visual Guide to Layout Managers.

If you post an screenshot of your application I'm pretty sure we can came up with a basic layout that you can work from.



来源:https://stackoverflow.com/questions/1836205/resizing-a-jframe

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!