<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Swing 布局管理 > 原文: [http://zetcode.com/tutorials/javaswingtutorial/swinglayoutmanagement/](http://zetcode.com/tutorials/javaswingtutorial/swinglayoutmanagement/) Java Swing 具有兩種組件:容器和子組件。 容器將子項分組為合適的布局。 要創建布局,我們使用布局管理器。 [Tweet](https://twitter.com/share) ZetCode 為 Swing 布局管理過程提供了 196 頁專門的電子書: [Java Swing 布局管理教程](/ebooks/javaswinglayout/) ## Swing 布局管理器 Swing 有大量可用的布局管理器-內置和第三方。 但是,大多數管理器都不適合現代 UI 的創建。 有三種可以正確完成工作的布局管理器: * `MigLayout` * `GroupLayout` * `FormLayout` `MigLayout`,`GroupLayout`和`FormLayout`是強大,靈活的布局管理器,可以滿足大多數布局要求。 在本教程中,我們使用`GroupLayout`管理器來設計用戶界面。 以下布局管理器已過時: * `FlowLayout` * `GridLayout` * `CardLayout` * `BoxLayout` * `GridBagLayout` 這些布局管理器無法滿足現代 UI 的要求。 ## 過時的管理器遇到的問題 過時的管理器要么太簡單(`FlowLayout`,`GridLayout`),要么就是不必要的復雜(`GridBagLayout`)。 所有這些管理器都有一個基本的設計錯誤:他們使用組件之間的固定間隙。 在組件之間使用剛性空間是不可移植的:一旦在不同的屏幕分辨率下運行程序,用戶界面就會損壞。 過時的管理器試圖通過一種稱為嵌套的技術來修復其弱點。 在嵌套中,開發者在多個面板中使用幾個不同的布局管理器。 盡管可以使用嵌套創建 UI,但它給代碼帶來了額外的不必要的復雜性。 ## 過時的管理器 在本節中,我們將介紹過時的布局管理器。 不建議使用這些管理器。 如果我們需要維護一些遺留代碼,只需花一些時間研究它們。 否則,應拒絕使用它們。 ### `FlowLayout`管理器 這是 Java Swing 工具箱中最簡單的布局管理器。 它是`JPanel`組件的默認布局管理器。 它是如此簡單,以至于不能用于任何實際布局。 許多 Java Swing 教程都介紹了該管理器,因此,初學者嘗試在其項目中使用它,而沒有意識到它不能用于任何嚴重的事情。 在計算其子大小時,流程布局使每個組件都假定其自然(首選)大小。 管理器將組件排成一排。 按順序添加了它們。 如果它們不適合一排,則進入下一排。 可以從右向左添加組件,反之亦然。 管理器允許對齊組件。 隱式地,組件居中,并且組件之間以及組件的邊緣與容器的邊緣之間有 5px 的空間。 ```java FlowLayout() FlowLayout(int align) FlowLayout(int align, int hgap, int vgap) ``` FlowLayout 管理器有三個可用的構造器。 第一個創建具有隱式值的管理器。 以 5px 水平和垂直空間居中。 其他允許指定這些參數。 `FlowLayoutEx.java` ```java package com.zetcode; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTree; import java.awt.Dimension; import java.awt.EventQueue; public class FlowLayoutEx extends JFrame { public FlowLayoutEx() { initUI(); } private void initUI() { var panel = new JPanel(); var button = new JButton("button"); panel.add(button); var tree = new JTree(); panel.add(tree); var area = new JTextArea("text area"); area.setPreferredSize(new Dimension(100, 100)); panel.add(area); add(panel); pack(); setTitle("FlowLayout example"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new FlowLayoutEx(); ex.setVisible(true); }); } } ``` 該示例顯示了窗口中的按鈕,樹組件和文本區域組件。 如果我們創建一個空樹組件,則組件內部會有一些默認值。 ```java var panel = new JPanel(); ``` `JPanel`組件的隱式布局管理器是`FlowLayout`。 我們不必手動設置。 ```java var area = new JTextArea("text area"); area.setPreferredSize(new Dimension(100, 100)); ``` 流布局管理器為其組件設置首選大小。 因此,在我們的案例中,區域組件將為`100x100px`。 如果我們未設置首選大小,則組件將具有其文本的大小。 沒有文本,該組件將根本不可見。 嘗試在區域組件中編寫或刪除一些文本。 組件將相應地增長和收縮。 ```java panel.add(area); ``` 該組件放置在帶有`add()`的容器內。 ![FlowLayout](https://img.kancloud.cn/fc/c5/fcc589bd4d23ef9d9d4128f86d05082a_287x135.jpg) 圖:`FlowLayout` ### `GridLayout` `GridLayout`布局管理器將組件布置在矩形網格中。 容器分為大小相等的矩形。 每個矩形中放置一個組件。 `GridLayout`非常簡單,不能用于任何實際布局。 `GridLayoutEx.java` ```java package com.zetcode; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import java.awt.EventQueue; import java.awt.GridLayout; public class GridLayoutEx extends JFrame { public GridLayoutEx() { initUI(); } private void initUI() { var panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panel.setLayout(new GridLayout(5, 4, 5, 5)); String[] buttons = { "Cls", "Bck", "", "Close", "7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", "0", ".", "=", "+" }; for (int i = 0; i < buttons.length; i++) { if (i == 2) { panel.add(new JLabel(buttons[i])); } else { panel.add(new JButton(buttons[i])); } } add(panel); setTitle("GridLayout"); setSize(350, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new GridLayoutEx(); ex.setVisible(true); }); } } ``` 該示例顯示了一個簡單計算器工具的框架。 我們在管理器中放入了 19 個按鈕和一個標簽。 請注意,每個按鈕的大小均相同。 ```java panel.setLayout(new GridLayout(5, 4, 5, 5)); ``` 在這里,我們為面板組件設置了網格布局管理器。 布局管理器采用四個參數。 行數,列數以及組件之間的水平和垂直間隙。 ![GridLayout](https://img.kancloud.cn/35/99/35997409ceb8f86b816508e0ff17cb3e_350x300.jpg) 圖:`GridLayout` ### `BorderLayout` `BorderLayout`是一個簡單的布局管理器,在某些布局中可以派上用場。 它是`JFrame`,`JWindow`,`JDialog`,`JInternalFrame`和`JApplet`的默認布局管理器。 它有一個嚴重的局限性-它以像素為單位設置子元素之間的間隙,從而創建了剛性的布局。 這導致了不可移植的 UI,因此不建議使用它。 `BorderLayout`將空間分為五個區域:北,西,南,東和中心。 每個區域只能有一個組件。 如果需要在一個區域中放置更多組件,則必須在其中放置一個由我們選擇的管理器組成的小組。 N,W,S,E 區域中的組件具有首選大小。 中間的組件占據了剩余的整個空間。 如果子組件彼此之間距離太近,則看起來不太好。 我們必須在它們之間留一些空間。 Swing 工具箱中的每個組件的邊緣都可以帶有邊框。 要創建邊框,我們可以創建`EmptyBorder`類的新實例,或者使用`BorderFactory`。 `BorderEx.java` ```java package com.zetcode; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Insets; public class BorderLayoutEx extends JFrame { public BorderLayoutEx() { initUI(); } private void initUI() { var bottomPanel = new JPanel(new BorderLayout()); var topPanel = new JPanel(); topPanel.setBackground(Color.gray); topPanel.setPreferredSize(new Dimension(250, 150)); bottomPanel.add(topPanel); bottomPanel.setBorder(new EmptyBorder(new Insets(20, 20, 20, 20))); add(bottomPanel); pack(); setTitle("BorderLayout"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new BorderLayoutEx(); ex.setVisible(true); }); } } ``` 該示例將顯示一個灰色面板及其周圍的邊框。 ```java var bottomPanel = new JPanel(new BorderLayout()); var topPanel = new JPanel(); ``` 我們將面板放入面板中。 底部面板具有`BorderLayout`管理器。 ```java bottomPanel.add(topPanel); ``` 在這里,我們將頂部面板放入底部面板組件中。 更準確地說,我們將其放置在`BorderLayout`管理器的中心區域。 ```java bottomPanel.setBorder(new EmptyBorder(new Insets(20, 20, 20, 20))); ``` 在這里,我們在底部面板周圍創建了 20px 的邊框。 邊框值如下:上,左,下和右。 請注意,創建固定的嵌入(空格)不是可移植的。 ![BorderLayout](https://img.kancloud.cn/b5/d5/b5d5078f3dba506d22cc06797f1d3848_292x215.jpg) 圖:`BorderLayout` 下一個示例顯示`BorderLayout`管理器的典型用法。 `BorderLayoutEx2.java` ```java package com.zetcode; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JTextArea; import javax.swing.JToolBar; import javax.swing.border.EmptyBorder; import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.Insets; public class BorderLayoutEx2 extends JFrame { public BorderLayoutEx2() { initUI(); } private void initUI() { var menubar = new JMenuBar(); var fileMenu = new JMenu("File"); menubar.add(fileMenu); setJMenuBar(menubar); var toolbar = new JToolBar(); toolbar.setFloatable(false); var exitIcon = new ImageIcon("src/resources/exit.png"); var exitBtn = new JButton(exitIcon); exitBtn.setBorder(new EmptyBorder(0, 0, 0, 0)); toolbar.add(exitBtn); add(toolbar, BorderLayout.NORTH); var vertical = new JToolBar(JToolBar.VERTICAL); vertical.setFloatable(false); vertical.setMargin(new Insets(10, 5, 5, 5)); var driveIcon = new ImageIcon("src/resources/drive.png"); var compIcon = new ImageIcon("src/resources/computer.png"); var printIcon = new ImageIcon("src/resources/printer.png"); var driveBtn = new JButton(driveIcon); driveBtn.setBorder(new EmptyBorder(3, 0, 3, 0)); var compBtn = new JButton(compIcon); compBtn.setBorder(new EmptyBorder(3, 0, 3, 0)); var printBtn = new JButton(printIcon); printBtn.setBorder(new EmptyBorder(3, 0, 3, 0)); vertical.add(driveBtn); vertical.add(compBtn); vertical.add(printBtn); add(vertical, BorderLayout.WEST); add(new JTextArea(), BorderLayout.CENTER); var statusbar = new JLabel(" Statusbar"); add(statusbar, BorderLayout.SOUTH); setSize(400, 350); setTitle("BorderLayout"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new BorderLayoutEx2(); ex.setVisible(true); }); } } ``` 該示例顯示了典型的應用框架。 我們顯示了一個垂直和水平工具欄,一個狀態欄和一個中央組件(文本區域)。 `BorderLayout`是`JFrame`容器的默認布局管理器。 因此,我們不必顯式設置它。 ```java add(toolbar, BorderLayout.NORTH); ``` 我們將工具欄放置在布局的北部。 ```java var driveBtn = new JButton(driveIcon); driveBtn.setBorder(new EmptyBorder(3, 0, 3, 0)); ``` 為了在按鈕周圍留一些空白,我們必須使用`EmptyBorder`。 這會在按鈕的頂部和底部增加一些固定的空間。 當我們添加固定空間時,UI 不可移植。 3px 的空間在 1280x720 的屏幕上可能看起來不錯,但在`1920x1200px`的屏幕上不合適。 ```java add(vertical, BorderLayout.WEST); ``` 我們將垂直太桿放在西邊。 ```java add(new JTextArea(), BorderLayout.CENTER); ``` 我們將文本區域放置在中間。 ```java add(statusbar, BorderLayout.SOUTH); ``` 狀態欄轉到南部區域。 ![BorderLayout 2](https://img.kancloud.cn/00/b7/00b7d556450e19f62cdeb9c2a7a47075_471x367.jpg) 圖:`BorderLayout` 2 ### `CardLayout` `CardLayout`是一個簡單的布局管理器,將每個組件都視為卡。 容器是這些卡的棧。 一次只能看到一個組件。 其余的隱藏。 最初顯示容器時,默認情況下將顯示添加到容器的第一個組件。 該管理器的實際用途有限。 它可用于創建向導或選項卡式窗格。 以下示例使用`CardLayout`管理器創建圖像庫。 我們使用了 Krasna Horka 城堡的四張圖片(2012 年大火之前)。 `CardLayoutEx.java` ```java package com.zetcode; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; import java.awt.EventQueue; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class CardLayoutEx extends JFrame { private ImageIcon horka1; private ImageIcon horka2; private ImageIcon horka3; private ImageIcon horka4; private ImageIcon previ; private ImageIcon nexti; private JPanel mainPanel; private CardLayout cardLayout; public CardLayoutEx() { initUI(); } private void initUI() { mainPanel = new JPanel(); mainPanel.setBackground(new Color(50, 50, 50)); mainPanel.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5) ); cardLayout = new CardLayout(); mainPanel.setLayout(cardLayout); horka1 = new ImageIcon("src/resources/horka1.jpg"); horka2 = new ImageIcon("src/resources/horka2.jpg"); horka3 = new ImageIcon("src/resources/horka3.jpg"); horka4 = new ImageIcon("src/resources/horka4.jpg"); previ = new ImageIcon("src/resources/previous.png"); nexti = new ImageIcon("src/resources/next.png"); var label1 = new JLabel(horka1); var label2 = new JLabel(horka2); var label3 = new JLabel(horka3); var label4 = new JLabel(horka4); mainPanel.add(label1); mainPanel.add(label2); mainPanel.add(label3); mainPanel.add(label4); add(mainPanel); var prevButton = new JButton(previ); prevButton.addActionListener((e) -> cardLayout.previous(mainPanel)); var nextButton = new JButton(nexti); nextButton.addActionListener((e) -> cardLayout.next(mainPanel)); var btnPanel = new JPanel(); btnPanel.setBackground(new Color(50, 50, 50)); btnPanel.add(prevButton); btnPanel.add(nextButton); add(btnPanel, BorderLayout.SOUTH); pack(); setTitle("Gallery"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new CardLayoutEx(); ex.setVisible(true); }); } } ``` 我們創建兩個按鈕來瀏覽圖像。 ```java mainPanel = new JPanel(); mainPanel.setBackground(new Color(50, 50, 50)); mainPanel.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5) ); ``` 我們創建主面板組件。 我們將其顏色設置為深灰色。 我們將 5px 放置在面板周圍,以使它的子級不太靠近窗口的邊界。 ```java cardLayout = new CardLayout(); mainPanel.setLayout(cardLayout); ``` `CardLayout`管理器已創建并設置到主面板。 ```java mainPanel.add(label1); mainPanel.add(label2); mainPanel.add(label3); mainPanel.add(label4); ``` 顯示圖像的標簽組件將添加到面板中。 ```java var prevButton = new JButton(previ); prevButton.addActionListener((e) -> cardLayout.previous(mainPanel)); ``` 單擊上一個按鈕,將調用管理器的`previous()`方法。 它會翻轉到指定容器的上一張卡片。 ```java add(mainPanel); ``` 我們將主面板添加到框架組件邊框布局的中心區域。 如果未明確指定放置組件的位置,則會將其添加到中心區域。 ```java var btnPanel = new JPanel(); btnPanel.setBackground(new Color(50, 50, 50)); btnPanel.add(prevButton); btnPanel.add(nextButton); ``` 這些按鈕將添加到按鈕面板。 ```java add(btnPanel, BorderLayout.SOUTH); ``` 最后,將帶有按鈕的面板放入`BorderLayout`管理器的南部區域。 ![CardLayout](https://img.kancloud.cn/76/a0/76a05492c1053fb59c4fb7bc054cc711_402x335.jpg) 圖:`CardLayout` ### `BoxLayout` `BoxLayout`管理器是一個簡單的布局管理器,用于組織列或行中的組件。 它可以使用嵌套創建非常復雜的布局。 但是,這增加了布局創建的復雜性,并使用了額外的資源,尤其是許多其他`JPanel`組件。 `BoxLayout`僅能創建固定空間; 因此,其布局不可移植。 `BoxLayout`具有以下構造器: ```java BoxLayout(Container target, int axis) ``` 構造器創建一個布局管理器,該管理器將沿給定軸布置組件。 與其他布局管理器不同,`BoxLayout`將容器實例作為構造器中的第一個參數。 第二個參數確定管理器的方向。 要創建一個水平框,我們可以使用`LINE_AXIS`常量。 要創建一個垂直框,我們可以使用`PAGE_AXIS`常量。 框布局管理器通常與`Box`類一起使用。 此類創建一些不可見的組件,這些組件會影響最終布局。 * 膠水 * 支撐 * 剛性區域 假設我們要在窗口的右下角放置兩個按鈕。 `BoxLayoutButtonsEx.java` ```java package com.zetcode; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Dimension; import java.awt.EventQueue; public class BoxLayoutButtonsEx extends JFrame { public BoxLayoutButtonsEx() { initUI(); } private void initUI() { var basePanel = new JPanel(); basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS)); add(basePanel); basePanel.add(Box.createVerticalGlue()); var bottomPanel = new JPanel(); bottomPanel.setAlignmentX(1f); bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS)); var okBtn = new JButton("OK"); var closeBtn = new JButton("Close"); bottomPanel.add(okBtn); bottomPanel.add(Box.createRigidArea(new Dimension(5, 0))); bottomPanel.add(closeBtn); bottomPanel.add(Box.createRigidArea(new Dimension(15, 0))); basePanel.add(bottomPanel); basePanel.add(Box.createRigidArea(new Dimension(0, 15))); setTitle("Two Buttons"); setSize(300, 150); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new BoxLayoutButtonsEx(); ex.setVisible(true); }); } } ``` 下圖說明了該示例。 ![Two buttons](https://img.kancloud.cn/04/89/0489b37e73abeeda232bbc266d2003b4_300x211.jpg) 圖:兩個按鈕 我們創建兩個面板。 基本面板具有垂直框布局。 底部面板有一個水平面板。 我們將底板插入底板。 底部面板右對齊。 窗口頂部和底部面板之間的空間是可擴展的。 這是通過垂直膠水實現的。 ```java basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS)); ``` 在這里,我們使用垂直`BoxLayout`創建一個基礎面板。 ```java var bottomPanel = new JPanel(); bottomPanel.setAlignmentX(1f); bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS)); ``` 底部面板右對齊。 這是通過`setAlignmentX()`方法完成的。 面板具有水平布局。 ```java bottomPanel.add(Box.createRigidArea(new Dimension(5, 0))); ``` 我們在按鈕之間留出一些剛性空間。 ```java basePanel.add(bottomPanel); ``` 在這里,我們將具有水平框布局的底部面板放置到垂直基礎面板上。 ```java basePanel.add(Box.createRigidArea(new Dimension(0, 15))); ``` 我們還在底部面板和窗口邊框之間留出一些空間。 ![BoxLayout buttons example](https://img.kancloud.cn/c4/62/c4625c3f17178c53fa1e26f7af9a4d4b_300x150.jpg) 圖:`BoxLayout`按鈕示例 當使用`BoxLayout`管理器時,可以在組件之間設置一個剛性區域。 `BoxLayoutRigidAreaEx.java` ```java package com.zetcode; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Insets; public class BoxLayoutRigidAreaEx extends JFrame { public BoxLayoutRigidAreaEx() { initUI(); } private void initUI() { var basePanel = new JPanel(); basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS)); basePanel.setBorder(new EmptyBorder(new Insets(40, 60, 40, 60))); basePanel.add(new JButton("Button")); basePanel.add(Box.createRigidArea(new Dimension(0, 5))); basePanel.add(new JButton("Button")); basePanel.add(Box.createRigidArea(new Dimension(0, 5))); basePanel.add(new JButton("Button")); basePanel.add(Box.createRigidArea(new Dimension(0, 5))); basePanel.add(new JButton("Button")); add(basePanel); pack(); setTitle("RigidArea"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new BoxLayoutRigidAreaEx(); ex.setVisible(true); }); } } ``` 在此示例中,我們顯示四個按鈕。 默認情況下,按鈕之間沒有空格。 為了在其中留出一些空間,我們增加了一些剛性區域。 ```java basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS)); ``` 我們為面板使用垂直`BoxLayout`管理器。 ```java basePanel.add(new JButton("Button")); basePanel.add(Box.createRigidArea(new Dimension(0, 5))); basePanel.add(new JButton("Button")); ``` 我們添加按鈕并使用`Box.createRigidArea()`在它們之間創建一個剛性區域。 ![Rigid area](https://img.kancloud.cn/5b/9b/5b9bb24f3ba581f9e208eb2cc2a04a15_204x220.jpg) 圖:`RigidArea` ### 每日提示 下一個示例創建“每日提示”窗口對話框。 我們結合使用各種布局管理器。 `TipOfDayEx.java` ```java package com.zetcode; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.JTextPane; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.event.KeyEvent; public class TipOfDayEx extends JDialog { public TipOfDayEx() { initUI(); } private void initUI() { var basePanel = new JPanel(); basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS)); add(basePanel); var topPanel = new JPanel(new BorderLayout(0, 0)); topPanel.setMaximumSize(new Dimension(450, 0)); var hint = new JLabel("Productivity Hints"); hint.setBorder(BorderFactory.createEmptyBorder(0, 25, 0, 0)); topPanel.add(hint); var icon = new ImageIcon("src/resources/coffee2.png"); var label = new JLabel(icon); label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); topPanel.add(label, BorderLayout.EAST); var separator = new JSeparator(); separator.setForeground(Color.gray); topPanel.add(separator, BorderLayout.SOUTH); basePanel.add(topPanel); var textPanel = new JPanel(new BorderLayout()); textPanel.setBorder(BorderFactory.createEmptyBorder(15, 25, 15, 25)); var pane = new JTextPane(); pane.setContentType("text/html"); var text = "<p><b>Closing windows using the mouse wheel</b></p>" + "<p>Clicking with the mouse wheel on an editor tab closes the window. " + "This method works also with dockable windows or Log window tabs.</p>"; pane.setText(text); pane.setEditable(false); textPanel.add(pane); basePanel.add(textPanel); var boxPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0)); var box = new JCheckBox("Show Tips at startup"); box.setMnemonic(KeyEvent.VK_S); boxPanel.add(box); basePanel.add(boxPanel); var bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); var tipBtn = new JButton("Next Tip"); tipBtn.setMnemonic(KeyEvent.VK_N); var closeBtn = new JButton("Close"); closeBtn.setMnemonic(KeyEvent.VK_C); bottomPanel.add(tipBtn); bottomPanel.add(closeBtn); basePanel.add(bottomPanel); bottomPanel.setMaximumSize(new Dimension(450, 0)); setTitle("Tip of the Day"); setSize(new Dimension(450, 350)); setResizable(false); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new TipOfDayEx(); ex.setVisible(true); }); } } ``` 該示例混合使用了布局管理器。 只需將四個面板放入垂直組織的基本面板中即可。 ```java var basePanel = new JPanel(); basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS)); add(basePanel); ``` 這是最底部的面板。 它具有垂直框布局管理器。 基本面板已添加到默認的`JDialog`組件。 默認情況下,此組件具有邊框布局管理器。 ```java var topPanel = new JPanel(new BorderLayout(0, 0)); ``` `topPanel`面板具有邊框布局管理器。 我們將包含三個組成部分。 兩個標簽和一個分隔符。 ```java topPanel.setMaximumSize(new Dimension(450, 0)); ``` 如果我們想要的面板不超過其組件,則必須設置其最大大小。 零值將被忽略。 管理器計算必要的高度。 ```java var textPanel = new JPanel(new BorderLayout()); ... textPanel.add(pane); ``` 文本窗格組件將添加到邊框布局管理器的中心區域。 它會占用所有剩余空間。 正是我們想要的。 ```java var boxPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0)); ``` 該復選框顯示在`boxPanel`面板中。 它保持對齊。 流布局管理器的水平間隙為 20px。 其他組件的像素為 25px。 這是為什么? 這是因為流布局管理器也在組件和邊緣之間放置了一些空間。 ```java var bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); ... bottomPanel.setMaximumSize(new Dimension(450, 0)); ``` 底部面板顯示兩個按鈕。 它具有右對齊的流布局管理器。 為了在對話框的右邊緣顯示按鈕,面板必須從頭到尾水平伸展。 ![Tip of the Day](https://img.kancloud.cn/e7/71/e771bda7a05b93978ff7eaab97c4276c_450x350.jpg) 圖:當天的提示 ## 沒有管理器 可以不使用布局管理器。 在少數情況下,我們可能不需要布局管理器。 (也許將一些圖像放置在一些不規則的位置。)但是在大多數情況下,要創建真正可移植的復雜應用,我們需要布局管理器。 如果沒有布局管理器,我們將使用絕對值來定位組件。 `AbsoluteLayoutEx.java` ```java package com.zetcode; import javax.swing.JButton; import javax.swing.JFrame; import java.awt.EventQueue; public class AbsoluteLayoutEx extends JFrame { public AbsoluteLayoutEx() { initUI(); } private void initUI() { setLayout(null); var okBtn = new JButton("OK"); okBtn.setBounds(50, 50, 80, 25); var closeBtn = new JButton("Close"); closeBtn.setBounds(150, 50, 80, 25); add(okBtn); add(closeBtn); setTitle("Absolute positioning"); setSize(300, 250); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public static void main(String[] args) { EventQueue.invokeLater(() -> { var ex = new AbsoluteLayoutEx(); ex.setVisible(true); }); } } ``` 這個簡單的示例顯示了兩個按鈕。 ```java setLayout(null); ``` 我們通過向`setLayout()`方法提供`null`使用絕對定位。 (`JFrame`組件具有默認的布局管理器`BorderLayout`。) ```java okBtn.setBounds(50, 50, 80, 25); ``` `setBounds()`方法放置“確定”按鈕。 參數是 x 和 y 坐標以及組件的寬度和高度。 ![Absolute layout](https://img.kancloud.cn/f3/0c/f30cbe31c60e0a515896b240668fbf61_300x250.jpg) 圖:絕對布局 在本章中,我們提到了 Swing 中的布局管理。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看