2014-06-27 349 views
1

所以我是一名計算機科學專業的學生,​​我已經完成了我的第一年。我想創建一個簡單的程序,我意識到我很厭煩不使用佈局;佈局 - 相對於屏幕尺寸

this.setLayout(null); 

爲每一個組件添加邊界是非常煩人的。那麼,我一直在使用JPanel組件和GridLayout很多,這使我的工作更容易一些。但我對此感到厭倦。

我非常關注GUI的外觀,並且在開始添加代碼的功能之前,使用幾乎一半的時間編程使GUI看起來不錯。通過不使用佈局和添加邊界,我被迫setResizable(false),因爲如果我改變JFrame的大小它看起來不好。

我一直在尋找一點,我知道BorderLayoutFlowLayout,但我不喜歡它們。是否有任何佈局可以保持組件相對於窗口大小的相對大小?

例如,我想作一個簡單的程序如下:(在Photoshop速寫)

enter image description here

我可以很容易地與3塊板做這一點,但正如我所說,如果我改變幀的大小一切都保持原位,而不是相對於窗口大小。

你們能幫我嗎?

+1

谷歌現在是你的導師http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html – Mindeater

+1

使用** [佈局組合](http://stackoverflow.com/a/5630271/ 418556) **,以及[白色空間]的佈局填充和邊框(http://stackoverflow.com/q/17874717/418556)。 –

+1

幫助的一些例子,[這裏](http://stackoverflow.com/a/11166903/1057230),[這裏](http://stackoverflow.com/a/17640318/1057230),[這裏](http: //stackoverflow.com/a/10596800/1057230)和[這裏](http://stackoverflow.com/a/17919032/1057230),特別是這最後一個鏈接:-) –

回答

3

這個設計尋找適合BorderLayout的地方,在NORTH你有values that changes CENTER你有主要部分,而SOUTH有你的按鈕。

Link to the Oracle Border Layout

您可以將此BorderLayout的到JFrame,然後創建3個JPanels每個北部,中部和南部部分。如果您想對組件和麪板使用響應式設計,請查看比GridLayout更靈活的GridBagLayout

+0

我知道Borderlayout。但我不喜歡它。除了擺動佈局經理之外,還有其他的東西嗎? – user3685412

+0

那麼根據圖片中的設計,你不需要比BorderLayout和GridBagLayout更多的東西。但是如果你堅持要看一些由程序員開發的定製佈局。但是,擺動佈局可以做你的application @ user3685412 – CMPS

+0

+1,我也同意這看起來是最好的佈局。通常,一個滾動窗格將被添加到CENTER中,以在框架調整大小時獲取所有可用空間。想想你正在使用的瀏覽器。標題欄,菜單和工具欄都是固定大小,並且瀏覽器窗口調整大小。然後,您可以使用帶有FlowLayout或GridLayout的面板作爲BorderLayout的南部。我會說一個FlowLayout是最好的,因爲它只是因爲你調整窗口大小而調整按鈕沒有意義。 – camickr

2

佈局管理是一個非常複雜的問題,我不認爲人們真的很欣賞它的真實性。

沒有一個佈局會實現您想要的一切,在大多數情況下,您需要採取兩個或更多佈局,特別是隨着您的要求變得更加複雜。

例如,下面是一個簡單的BorderLayout在基部並且使用FlowLayout

LayoutLayout

它是通過使用

JList listOfThings = new JList(...); 
JTextField tf = new JTextField(); 

JButton add = new JButton("Add"); 
JButton delete = new JButton("Delete"); 
JButton go = new JButton("Go..."); 

JPanel buttons = new JPanel(); 
buttons.add(add); 
buttons.add(delete); 
buttons.add(go); 

add(new BorderLayout()); 
add(tf, BorderLayout.NORTH); 
add(new JScrollPane(listOfThings)); 
add(buttons, BorderLayout.SOUTH); 

對於更復雜的實現上的JPanel的按鈕佈局,我會考慮使用類似GridBagLayout。您可能還需要考慮MigLayout作爲替代

看看Laying Out Components Within a Container瞭解更多詳細的使用佈局管理器

2

我想使用的BorderLayout和BoxLayout的組合。 BorderLayout允許我根據相對位置的關係放置組件,BoxLayout讓我管理細微的距離(創建一些空白區域)。你可以使用component.setBorder(BorderFactory.createEmptyBorder(top,left,bottom,right));也實現了這個目標。

這裏是一個演示,並希望它可以幫助你。

import java.awt.BorderLayout; 
import java.awt.Color; 

import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 
import javax.swing.event.ListSelectionEvent; 
import javax.swing.event.ListSelectionListener; 

public class LayoutTest{ 

    private JTextField jTextField; 

    public void createUI(){ 
     JFrame frame = new JFrame("Layout Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(true); 

     JPanel mainPanel = new JPanel(); 
     mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
     mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); 


     mainPanel.add(new TextFieldPanel()); 

     mainPanel.add(Box.createVerticalStrut(8)); 

     mainPanel.add(new ListPanel()); 

     mainPanel.add(Box.createVerticalStrut(8)); 

     mainPanel.add(new ButtonPanel()); 

     frame.add(mainPanel,BorderLayout.CENTER); 

     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 

    } 

    public static void main(String[] args) { 
     LayoutTest layoutTest = new LayoutTest(); 
     layoutTest.createUI(); 
    } 


    @SuppressWarnings("serial") 
    class TextFieldPanel extends JPanel{ 
     public TextFieldPanel(){ 
      setLayout(new BorderLayout()); 
      jTextField = new JTextField(); 
      jTextField.setEditable(false); 
      add(jTextField,BorderLayout.CENTER); 
     } 
    } 

    @SuppressWarnings("serial") 
    class ListPanel extends JPanel implements ListSelectionListener{ 
     private JList<String> list; 

     public ListPanel(){ 
      setLayout(new BorderLayout()); 
      String stringArr[] = new String[30]; 
      for (int i = 0; i < 30; i++) { 
       stringArr[i] = "JList :This line is item" + i; 
      } 
      list = new JList<String>(stringArr); 
      JScrollPane scrollPane = new JScrollPane(list); 
      add(scrollPane,BorderLayout.CENTER); 
      setBackground(new Color(211,211,211)); 

      list.addListSelectionListener(this); 
     } 

     @Override 
     public void valueChanged(ListSelectionEvent e) { 
      // TODO Auto-generated method stub 
      jTextField.setText(list.getSelectedValue()); 
     } 
    } 

    @SuppressWarnings("serial") 
    class ButtonPanel extends JPanel{ 
     public ButtonPanel(){  
      JButton button1 = new JButton("Button1"); 
      JButton button2 = new JButton("Button2"); 
      JButton button3 = new JButton("Button3"); 

      setLayout(new BorderLayout()); 
      add(button1,BorderLayout.WEST); 
      add(button2,BorderLayout.CENTER); 
      add(button3,BorderLayout.EAST); 
     } 
    } 
} 

下面是效果:

enter image description here

enter image description here

可以使用BoxLayout的爲ButtonPanel如果你不想讓按鈕的大小變化。

@SuppressWarnings("serial") 
class ButtonPanel extends JPanel{ 
    public ButtonPanel(){  
     JButton button1 = new JButton("Button1"); 
     JButton button2 = new JButton("Button2"); 
     JButton button3 = new JButton("Button3"); 

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

     add(button1); 
     add(Box.createHorizontalStrut(8)); 
     add(button2); 
     add(Box.createHorizontalStrut(8)); 
     add(button3); 
    } 
} 

,效果是這樣的:

enter image description here

要了解詳情,有關使用的BoxLayout產生的空白,你可以參考https://stackoverflow.com/a/22525005/3378204

0

HVLayout保持組件的相對大小就窗口大小而言,也就是說,如果將組件配置爲具有相對大小(例如,按鈕通常不會增長或縮小 - 它們將保持其首選大小)。這個SO問題是我推動HVLayout發佈的動機之一,並且包含一個屏幕截圖(顯示大窗口大小,小尺寸和首選「默認」大小):
rel-to-window
該窗口的源代碼位於RelativeToWindowSize.java
一位來自HVLayout助手類的用於建立窗口,所以我不認爲這將是多大用處在這裏,但得到的印象,下面所示的「建窗口」部分:

public RelativeToWindowSize build() { 

    CSize cs = new CSize(); 
    CForm form = new CForm(new VBox(new Insets(2, 4, 2, 4)), cs); 
    addTitledBorder(form.get(), "Vertical box", Color.BLACK); 
    form.add(new JScrollPane(
       tfield = new JTextArea("Value that changes with value choosen from list.\nhttp://stackoverflow.com/questions/24462297/layout-relative-to-screensize/") 
      )).csize().setAreaSize(1.0f, 2.5f).fixedMinHeight().setMaxHeight(4.0f); 
    // tfield shows mono-spaced font by default. 
    tfield.setFont(SwingUtils.getUIFont()); 
    form.add(new JScrollPane(vlist = new JList<String>(getListValues()))) 
      .csize().setAreaSize(1.0f, 5.0f); 

    form.addChild(new HBox()); 
    addTitledBorder(form.get(), "Horizontal box", Color.RED); 
    form.addChild(new HBox(SwingConstants.CENTER)); 
    addTitledBorder(form.get(), "Centered box.", Color.BLUE); 
    form.add(createButton(cs, "Add")); 
    form.add(createButton(cs, "Modify")); 
    form.up(); 
    form.addChild(new HBox(SwingConstants.TRAILING)); 
    addTitledBorder(form.get(), "Trailing box", Color.GREEN); 
    form.add(createButton(cs, "Delete")); 

    setContentPane(form.getRoot()); 
    pack(); 
    setLocationByPlatform(true); 
    //applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 
    vlist.addListSelectionListener(this); 
    log.debug(getClass().getName() + " build."); 
    return this; 
} 

private Component createButton(CSize cs, String text) { 
    // For purpose of demo, let button shrink in width. 
    return cs.set(new TButton(text)).setFixed().shrinkWidth(0.33f).get(); 
}