ฉันควรหลีกเลี่ยงการใช้วิธีกำหนดขนาด (ที่ต้องการ | สูงสุด | ต่ำสุด) ใน Java Swing หรือไม่


481

หลายครั้งที่ฉันถูกวิพากษ์วิจารณ์ว่ามีการแนะนำให้ใช้วิธีการต่อไปนี้:

  1. setPreferredSize
  2. setMinimumSize
  3. setMaximumSize

บนSwingส่วนประกอบ ฉันไม่เห็นทางเลือกอื่นใดสำหรับการใช้งานของพวกเขาเมื่อฉันต้องการกำหนดสัดส่วนระหว่างส่วนประกอบที่แสดง ฉันได้รับการบอกเรื่องนี้:

ด้วยเลย์เอาต์คำตอบเหมือนกันเสมอ: ใช้ LayoutManager ที่เหมาะสม

ฉันค้นหาเว็บเล็กน้อย แต่ฉันไม่พบการวิเคราะห์ที่ครอบคลุมเกี่ยวกับเรื่องนี้ ดังนั้นฉันมีคำถามต่อไปนี้:

  1. ฉันควรหลีกเลี่ยงการใช้วิธีการเหล่านั้นอย่างสมบูรณ์หรือไม่?
  2. มีการกำหนดวิธีการด้วยเหตุผล ดังนั้นเมื่อไรฉันจึงควรใช้ ในบริบทใด มีวัตถุประสงค์อะไร?
  3. อะไรคือผลกระทบด้านลบจากการใช้วิธีการเหล่านั้น? (ฉันคิดได้แค่เพิ่มความสะดวกในการพกพาระหว่างระบบที่มีความละเอียดหน้าจอต่างกัน)
  4. ฉันไม่คิดว่า LayoutManager ใด ๆ สามารถตอบสนองทุกรูปแบบที่ต้องการได้อย่างแท้จริง ฉันจำเป็นต้องใช้ LayoutManager ใหม่สำหรับรูปแบบเล็ก ๆ น้อย ๆ ทุกรูปแบบหรือไม่
  5. หากคำตอบของ 4 คือ "ใช่" สิ่งนี้จะนำไปสู่การเพิ่มจำนวนคลาส LayoutManager ซึ่งจะยากต่อการรักษาหรือไม่?
  6. ในสถานการณ์ที่ฉันต้องกำหนดสัดส่วนระหว่างลูกของ Component (เช่น child1 ควรใช้พื้นที่ 10%, child2 40%, child3 50%) เป็นไปได้หรือไม่ที่จะใช้ LayoutManager แบบกำหนดเองได้?

คำตอบ:


236
  1. ฉันควรหลีกเลี่ยงการใช้วิธีการเหล่านั้นอย่างสมบูรณ์หรือไม่?

    ใช่สำหรับรหัสแอปพลิเคชัน

  2. มีการกำหนดวิธีการด้วยเหตุผล ดังนั้นเมื่อไรฉันจึงควรใช้ ในบริบทใด มีวัตถุประสงค์อะไร?

    ฉันไม่รู้ส่วนตัวว่าฉันคิดว่ามันเป็นอุบัติเหตุการออกแบบ API บังคับเล็กน้อยโดยส่วนประกอบประกอบที่มีแนวคิดพิเศษเกี่ยวกับขนาดของเด็ก "เล็กน้อย" เพราะพวกเขาควรจะนำความต้องการของพวกเขาไปใช้กับ LayoutManager ที่กำหนดเอง

  3. อะไรคือผลกระทบด้านลบจากการใช้วิธีการเหล่านั้น? (ฉันคิดได้แค่เพิ่มความสะดวกในการพกพาระหว่างระบบที่มีความละเอียดหน้าจอแตกต่างกัน)

    บางคน (ที่ไม่สมบูรณ์และน่าเสียดายที่การเชื่อมโยงจะแตกเนื่องจากการย้ายถิ่นของ SwingLabs เพื่อ java.net) ด้วยเหตุผลทางเทคนิคนี้ใช้สำหรับอินสแตนซ์ที่กล่าวถึงในกฎ (ฮิฮิ)หรือในการเชื่อมโยง @bendicott พบใน / แสดงความคิดเห็นของตนเพื่อคำตอบของฉัน ในทางสังคมวางตัวเป็นตันต่อเพื่อนที่โชคร้ายของคุณที่ต้องรักษารหัสและต้องติดตามโครงร่างที่เสียหาย

  4. ฉันไม่คิดว่า LayoutManager ใด ๆ สามารถตอบสนองทุกรูปแบบที่ต้องการได้อย่างแท้จริง ฉันจำเป็นต้องใช้ LayoutManager ใหม่สำหรับรูปแบบเล็ก ๆ น้อย ๆ ทุกรูปแบบของฉันหรือไม่

    ใช่มี LayoutManagers ที่ทรงพลังพอที่จะตอบสนองการประมาณการที่ดีมากกับ "ความต้องการเลย์เอาต์ทั้งหมด" สามตัวใหญ่คือ JGoodies FormLayout, MigLayout, DesignGridLayout ดังนั้นในทางปฏิบัติคุณไม่ค่อยเขียน LayoutManagers ยกเว้นสภาพแวดล้อมที่มีความเชี่ยวชาญสูง

  5. หากคำตอบของ 4 คือ "ใช่" สิ่งนี้จะนำไปสู่การเพิ่มจำนวนคลาส LayoutManager ซึ่งจะยากต่อการรักษาหรือไม่?

    (คำตอบของ 4 คือ "ไม่")

  6. ในสถานการณ์ที่ฉันต้องกำหนดสัดส่วนระหว่างลูกของ Component (ตัวอย่างเช่น child 1 ควรใช้พื้นที่ 10%, child 2 40%, child 3 50%) เป็นไปได้หรือไม่ที่จะใช้ LayoutManager แบบกำหนดเองได้?

    บิ๊กทรีใด ๆ ไม่สามารถแม้แต่กระทั่ง GridBag (ไม่เคยใส่ใจที่จะเชี่ยวชาญอย่างแท้จริงปัญหามากเกินไปสำหรับการใช้พลังงานน้อยเกินไป)


4
ฉันไม่แน่ใจทั้งหมดฉันเห็นด้วยกับคำแนะนำนี้อย่างน้อยสองสถานการณ์ 1) องค์ประกอบการแสดงผลที่กำหนดเอง 2) การใช้JEditorPaneกับ HTML ที่ไม่แนะนำความกว้าง OTOH ฉันไม่แน่ใจว่าฉันพลาดอะไรไปหรือเปล่า ฉันจะตรวจสอบคำตอบของเธรดอย่างระมัดระวัง แต่สนใจหากคุณมีความคิดเห็นใด ๆ โดยเฉพาะอย่างยิ่งในกรณีหลัง
Andrew Thompson

2
@ Andrew Thompson 1) comps ที่กำหนดเอง: มันเป็น comp ที่รับผิดชอบในการส่งคืนคำแนะนำเลย์เอาต์ที่เป็นประโยชน์ถ้าพวกเขาไม่ได้ impl คือ buggy 2) แม้ comps หลักจะเป็น buggy ;-) 3) ฉันไม่คำนึงถึงพื้นที่สีขาว โดยเจตนาในครั้งนี้ขอขอบคุณ :-)
kleopatra

8
ฉันไม่อยากเชื่อเลยว่าคำตอบที่ได้รับการยอมรับคือคำตอบที่หลีกเลี่ยงการใช้วิธี setXXX () บางครั้งคุณก็ต้องการให้พวกเขาให้คำแนะนำแก่ผู้จัดการเค้าโครง หากคุณกำลังวางแผงคุณควรใช้วิธีการเหล่านี้เมื่อจำเป็น บอกว่าฉันคิดว่าถ้าคุณใช้ตัวจัดการเลย์เอาต์ที่เหมาะสมคุณจะพบว่าตัวเองไม่จำเป็นต้องใช้วิธีการเหล่านี้บ่อยนัก แต่ในบางครั้งคุณก็แค่ต้องการมัน ลองใส่ JComboBox หรือ JSpinner ใน X_AXIS BoxLayout และไม่ใช้พวกเขาเชื่อว่าคุณจะพบว่าคุณต้องการ setMaximumSize () ที่นั่น
Michael

5
@Michael ไม่มีฉันอย่างไม่จำเป็นต้องใช้มัน - คำตอบอยู่เสมอที่จะใช้ดี LayoutManager และดำเนินการใด ๆ ปรับ tweaking บนผู้จัดการระดับ (เทียบกับระดับ Component)
kleopatra

5
คุณบอกว่า "ใช้ LayoutManager ที่เหมาะสมและบอกว่าขนาดที่คุณต้องการ" ทั้งหมดใน stackoverflow แต่คุณไม่เคยให้ตัวอย่างที่เฉพาะเจาะจงของ LayoutManager "ดี" และผู้จัดการมาตรฐานไม่อนุญาตให้ควบคุมขนาดโดยตรง
Ti Strga

100

การวิเคราะห์พฤติกรรมสองสามประการ:

  • อย่าใช้set[Preferred|Maximum|Minimum]Size()เมื่อคุณจริงๆหมายถึงแทนที่get[Preferred|Maximum|Minimum]Size()เช่นอาจจะมีการดำเนินการในการสร้างองค์ประกอบของคุณเองที่แสดงไว้ที่นี่

  • อย่าใช้set[Preferred|Maximum|Minimum]Size()เมื่อคุณสามารถพึ่งพาการเขียนทับส่วนประกอบอย่างgetPreferred|Maximum|Minimum]Sizeที่แสดงไว้ที่นี่และด้านล่าง

  • จะใช้set[Preferred|Maximum|Minimum]Size()ในการโพสต์การสืบทอดมาvalidate()รูปทรงเรขาคณิตที่แสดงด้านล่างและที่นี่

  • หากส่วนประกอบไม่มีขนาดที่ต้องการเช่นJDesktopPaneคุณอาจต้องกำหนดขนาดของคอนเทนเนอร์ แต่ตัวเลือกใด ๆ นั้นเป็นไปตามอำเภอใจ ความคิดเห็นอาจช่วยชี้แจงเจตนา

  • พิจารณารูปแบบทางเลือกหรือกำหนดเองเมื่อคุณพบว่าคุณจะต้องห่วงผ่านองค์ประกอบหลายอย่างเพื่อให้ได้ขนาดที่ได้มาเป็นที่กล่าวถึงเหล่านี้ในการแสดงความคิดเห็น

ป้อนคำอธิบายรูปภาพที่นี่

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * @see /programming/7229226
 * @see /programming/7228843
 */
public class DesignTest {

    private List<JTextField> list = new ArrayList<JTextField>();
    private JPanel panel = new JPanel();
    private JScrollPane sp = new JScrollPane(panel);

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                DesignTest id = new DesignTest();
                id.create("My Project");
            }
        });
    }

    private void addField(String name) {
        JTextField jtf = new JTextField(16);
        panel.add(new JLabel(name, JLabel.LEFT));
        panel.add(jtf);
        list.add(jtf);
    }

    private void create(String strProjectName) {
        panel.setLayout(new GridLayout(0, 1));
        addField("First Name:");
        addField("Last Name:");
        addField("Address:");
        addField("City:");
        addField("Zip Code:");
        addField("Phone:");
        addField("Email Id:");
        KeyboardFocusManager.getCurrentKeyboardFocusManager()
            .addPropertyChangeListener("permanentFocusOwner",
            new FocusDrivenScroller(panel));
        // Show half the fields
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        sp.validate();
        Dimension d = sp.getPreferredSize();
        d.setSize(d.width, d.height / 2);
        sp.setPreferredSize(d);

        JInternalFrame internaFrame = new JInternalFrame();
        internaFrame.add(sp);
        internaFrame.pack();
        internaFrame.setVisible(true);

        JDesktopPane desktopPane = new JDesktopPane();
        desktopPane.add(internaFrame);

        JFrame frmtest = new JFrame();
        frmtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmtest.add(desktopPane);
        frmtest.pack();
        // User's preference should be read from java.util.prefs.Preferences
        frmtest.setSize(400, 300);
        frmtest.setLocationRelativeTo(null);
        frmtest.setVisible(true);
        list.get(0).requestFocusInWindow();
    }

    private static class FocusDrivenScroller implements PropertyChangeListener {

        private JComponent parent;

        public FocusDrivenScroller(JComponent parent) {
            this.parent = parent;
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Component focused = (Component) evt.getNewValue();
            if (focused != null
                && SwingUtilities.isDescendingFrom(focused, parent)) {
                parent.scrollRectToVisible(focused.getBounds());
            }
        }
    }
}

2
ไม่เห็นด้วย (ตามที่คุณคาดเดา :-) ด้วยการให้เหตุผลโดย "ปัจจัยภายนอก": คุณสมบัติ XXSize มีไว้เพื่อแสดงความต้องการภายในเท่านั้น การดัดแปลงจากภายนอกนั้นเป็นการใช้งานผิด ๆ หรือการแฮ็ค ถ้าคุณต้องการเฟรม (ภายใน - หรือ J-) ที่มีขนาด aa specifc เทียบกับที่ต้องการ ... ปรับขนาดเฟรมไม่ใช่เนื้อหา
kleopatra

2
@ คลีโอพัตรา: จะยืนยงนิดหน่อย: ถ้าวิธีการ setXXSize ไม่เคยถูกนำมาใช้จากภายนอกทำไมไม่ประกาศเป็นส่วนตัวหรือได้รับการปกป้อง? นี่ไม่ใช่การออกแบบที่ขาดหรือไม่ ตัวดัดแปลงสาธารณะไม่บอกผู้ใช้โดยนัยว่าสามารถใช้วิธีการเหล่านั้นได้หรือไม่
Heisenbug

2
ฉันต้องเห็นด้วยกับ @kleopatra: setPreferredSize()แทนที่การคำนวณส่วนประกอบด้วยตัวเลือกโดยพลการเสมอ
trashgod

1
@trashgod ให้กับคุณ 100 ฉันคิดว่าไม่มีปัญหากับการเอาชนะวิธีการเหล่านี้แม้แต่เรียกพวกเขา (แต่แน่นอนว่านี่หมายความว่าคุณมีองค์ประกอบที่กำหนดเองดังนั้นการเอาชนะจะดีกว่า)
David Kroukamp

5
@DavidKroukamp: ขอบคุณ ฉันชอบที่จะได้รับประสบการณ์ที่ดีกว่าของ kleopatra แต่ฉันเห็นคุณค่าในการตรวจสอบมุมมองที่ตรงกันข้าม
trashgod

47

ฉันควรหลีกเลี่ยงการใช้วิธีการเหล่านั้นอย่างสมบูรณ์หรือไม่?

ไม่ไม่มีหลักฐานอย่างเป็นทางการที่จะแนะนำการโทรหรือการเอาชนะวิธีการเหล่านี้ไม่ได้รับอนุญาต ในความเป็นจริงของออราเคิลกล่าวว่าวิธีการเหล่านี้ถูกนำมาใช้สำหรับการให้คำแนะนำขนาด: http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment

พวกเขาอาจถูกแทนที่ (ซึ่งเป็นแนวทางปฏิบัติที่ดีที่สุดสำหรับการแกว่ง) เมื่อขยายองค์ประกอบสวิง (แทนที่จะเรียกวิธีการในอินสแตนซ์องค์ประกอบที่กำหนดเอง)

สิ่งสำคัญที่สุดไม่ว่าคุณจะระบุขนาดของส่วนประกอบอย่างไรให้แน่ใจว่าคอนเทนเนอร์ของส่วนประกอบของคุณใช้ตัวจัดการโครงร่างที่เคารพขนาดที่ร้องขอของส่วนประกอบ

มีการกำหนดวิธีการด้วยเหตุผล ดังนั้นเมื่อไรฉันจึงควรใช้ ในบริบทใด มีวัตถุประสงค์อะไร?

เมื่อคุณต้องการให้คำแนะนำขนาดที่กำหนดเองให้กับผู้จัดการคอนเทนเนอร์เค้าโครงเพื่อให้องค์ประกอบจะได้รับการจัดวางอย่างดี

อะไรคือผลกระทบด้านลบจากการใช้วิธีการเหล่านั้น? (ฉันคิดได้เพียงว่าจะเพิ่มความสะดวกในการพกพาระหว่างระบบที่มีความละเอียดหน้าจอแตกต่างกัน)

  • ผู้จัดการเลย์เอาต์หลายคนไม่สนใจขนาดสูงสุดของส่วนประกอบที่ร้องขอ อย่างไรก็ตามBoxLayoutและSpringLayoutทำ นอกจากนี้GroupLayoutยังมีความสามารถในการตั้งค่าขนาดต่ำสุดที่ต้องการหรือขนาดสูงสุดอย่างชัดเจนโดยไม่ต้องสัมผัสส่วนประกอบ

  • ตรวจสอบให้แน่ใจว่าคุณจำเป็นต้องกำหนดขนาดที่แน่นอนของส่วนประกอบ แต่ละส่วนประกอบของ Swing มีขนาดที่ต้องการแตกต่างกันไปขึ้นอยู่กับแบบอักษรที่ใช้และรูปลักษณ์ ดังนั้นการมีขนาดที่กำหนดอาจสร้างรูปลักษณ์ที่แตกต่างกันของ UI บนระบบที่แตกต่างกัน

  • บางครั้งปัญหาสามารถพบได้GridBagLayoutและเขตข้อมูลข้อความนั้นถ้าขนาดของภาชนะที่มีขนาดเล็กกว่าขนาดที่ต้องการขนาดที่น้อยที่สุดได้รับการใช้ซึ่งสามารถทำให้ช่องข้อความที่จะหดตัวค่อนข้างมาก

  • JFrameไม่บังคับ overriden getMinimumSize()เพียงเรียกsetMinimumSize(..)การทำงานของมัน

ฉันไม่คิดว่า LayoutManager ใด ๆ สามารถตอบสนองทุกรูปแบบที่ต้องการได้อย่างแท้จริง ฉันจำเป็นต้องใช้ LayoutManager ใหม่สำหรับรูปแบบเล็ก ๆ น้อย ๆ ทุกรูปแบบของฉันหรือไม่

ถ้าใช้คุณหมายถึงใช้ใช่ ไม่มีใครLayoutMangerสามารถจัดการทุกอย่างแต่ละคนLayoutManagerมีข้อดีและข้อเสียของมันดังนั้นแต่ละคนสามารถใช้ร่วมกันเพื่อผลิตเค้าโครงสุดท้าย

อ้างอิง:


3
ให้คำแนะนำขนาดที่กำหนดเองซึ่งเป็นข้อขัดแย้งในตัวเอง: การให้คำแนะนำการปรับขนาด (ใน px!) เป็นงานพิเศษของส่วนประกอบ จะคำนวณพวกเขาตามรายละเอียดสถานะภายในที่ไม่มีฝ่ายอื่นยกเว้นตัวเองสามารถรู้ได้ (และไม่สามารถติดตาม) จากมุมมองของลูกค้าวิธีการปรับแต่งสามารถเป็น LayoutManager ที่เหมาะสมและ / หรือเชี่ยวชาญ API ในองค์ประกอบที่ช่วยให้การกำหนดความต้องการขนาดในแง่ของคุณสมบัติที่เกี่ยวข้องกับความหมาย "ความหมาย" ขนาดจำนวนแถว / คอลัมน์ในองค์ประกอบข้อความ
kleopatra

3
@kleopatra ฉันยังคงอยากรู้ว่าทำไม Oracle จึงบอกเราถึงวิธีการใช้วิธีการเหล่านี้และวิธีการใช้งานที่ถูกต้อง เราอาจมีการตั้งค่าของเราเอง แต่เราไม่สามารถพูดได้ว่านักออกแบบระบุว่าไม่ควรใช้เมื่อไม่มีหลักฐานที่จะแนะนำสิ่งนี้ แต่นั่นเป็นเหตุผลว่าทำไมฉันถึงมองว่าถ้ามันจะดึงดูดผู้อื่นที่สามารถให้ข้อมูลจากแหล่งข้อมูลที่น่าเชื่อถือที่ oracle ระบุว่าจะไม่ใช้วิธีการเหล่านี้เลย (เช่นทำให้มันแย่ถ้าคุณทำเช่น setMinimumSize เรียกสิ่งต่าง ๆ เช่น JSplitPane ฯลฯ นี้สามารถเห็นได้ในบทช่วยสอนของ Oracle ของบานหน้าต่างแยก
David Kroukamp

4
@David: ฉันมาเพื่อดูsetXxxSizeวิธีการเป็นธงสีแดงที่ฉันอาจท้ายที่นี่แม้ว่าเอกสารแนะนำให้มัน ฉันควรจะเขียนทับเกือบทุกgetXxxSizeครั้งที่มีการเข้าถึงรูปทรงเรขาคณิตที่ต้องการ; และแม้แต่ตัวอย่างสั้น ๆ ก็นำกลับมาใช้ใหม่ได้มากกว่าที่ฉันต้องการคิด +1 สำหรับการกล่าวถึงความแตกต่างระหว่างผู้จัดการโครงร่างและการอ้างถึงบทช่วยสอน
trashgod

1
D'โอ้ในความคิดเห็นของฉันข้างต้นผมหมายถึงการอ้างถึงคำตอบที่นี่
trashgod

13
+1 "ไม่ไม่มีหลักฐานอย่างเป็นทางการที่จะแนะนำการโทรหรือการเอาชนะวิธีการเหล่านี้ไม่ได้รับอนุญาต" จับได้เห็นชัดตรงเผง. โพสต์แท็กเป็นคำตอบธรรมดาชัด ๆ
TT

25

มีจำนวนมากของคำตอบที่ดีที่นี่มี แต่ฉันต้องการที่จะเพิ่มเล็ก ๆ น้อย ๆ เพิ่มเติมเกี่ยวกับเหตุผลที่ว่าทำไมคุณตามปกติควรหลีกเลี่ยงการเหล่านี้ (คำถามเพียงแค่ขึ้นมาอีกครั้งในหัวข้อที่ซ้ำกัน):

ด้วยข้อยกเว้นเล็กน้อยหากคุณใช้วิธีการเหล่านี้คุณอาจปรับแต่ง GUI ของคุณให้ดูดีในรูปลักษณ์และสัมผัสที่เฉพาะเจาะจง (และด้วยการตั้งค่าเฉพาะระบบของคุณเช่นแบบอักษรบนเดสก์ท็อปที่คุณต้องการเป็นต้น) วิธีการที่ตัวเองไม่ได้ชั่วร้ายโดยเนื้อแท้ แต่เหตุผลทั่วไปสำหรับการใช้พวกเขาเป็น ทันทีที่คุณเริ่มปรับตำแหน่งพิกเซลและขนาดในเลย์เอาต์คุณจะเสี่ยงต่อการแตก GUI (หรืออย่างน้อยก็ดูไม่ดี) บนแพลตฟอร์มอื่น ๆ

ตัวอย่างนี้ลองเปลี่ยนรูปลักษณ์และความรู้สึกเริ่มต้นของแอปพลิเคชันของคุณ แม้จะมีเพียงตัวเลือกที่มีอยู่ในแพลตฟอร์มของคุณคุณอาจประหลาดใจกับผลลัพธ์ที่ไม่ดี

ดังนั้นในชื่อของการรักษา GUI ของคุณและดูดีในทุกแพลตฟอร์ม (จำไว้ว่าหนึ่งในผลประโยชน์ที่สำคัญของ Java คือ cross-platformness) คุณควรพึ่งพาผู้จัดการเลย์เอาต์ ฯลฯ เพื่อปรับขนาดของ ส่วนประกอบของคุณเพื่อให้แสดงผลอย่างถูกต้องนอกสภาพแวดล้อมการพัฒนาเฉพาะของคุณ

จากทั้งหมดที่กล่าวมาคุณสามารถเข้าใจสถานการณ์ที่วิธีการเหล่านี้เป็นธรรม อีกครั้งพวกเขาไม่ได้ชั่วร้ายโดยเนื้อแท้ แต่การใช้งานของพวกเขาเป็นธงสีแดงขนาดใหญ่ที่บ่งบอกถึงปัญหา GUI ที่อาจเกิดขึ้น เพียงให้แน่ใจว่าคุณตระหนักถึงความเป็นไปได้สูงที่จะเกิดภาวะแทรกซ้อนหาก / เมื่อคุณใช้มันและพยายามและคิดเสมอว่ามีวิธีแก้ปัญหาที่เป็นอิสระจากรูปลักษณ์และความรู้สึกอิสระ - บ่อยครั้งกว่าคุณจะพบว่าสิ่งเหล่านี้ วิธีการไม่จำเป็น

โดยวิธีการที่ถ้าคุณพบว่าตัวเองได้รับความผิดหวังกับผู้จัดการรูปแบบมาตรฐานมีจำนวนมากของดีฟรีเปิดแหล่งที่มาคนของบุคคลที่สามเช่นJGoodies'FormLayoutMigLayoutหรือ บางคนสร้าง GUI ได้มีการสนับสนุนในตัวสำหรับผู้บริหารรูปแบบของบุคคลที่สาม - คราสบรรณาธิการ WindowBuilder GUI เช่นเรือด้วยการสนับสนุนและFormLayoutMigLayout


2
+1 คำตอบที่มีน้ำใจ - เพียงไม่เห็นด้วยกับพวกเขาไม่ใช่ความชั่วร้ายโดยเนื้อแท้เพียงเพราะ :-) โดยทั่วไปแล้วลูกค้าภายนอกไม่มีโอกาสที่จะคาดเดา - และเพียงแค่สมมุติว่าใกล้เคียงกับคนภายนอกเท่านั้น ส่วนประกอบเองมีข้อมูลทั้งหมดตลอดเวลาเพื่อส่งคืนสิ่งที่มีประโยชน์ และเนื่องจากช่วงเวลาที่คนนอกแทรกแซงมันเป็นความรับผิดชอบของพวกเขาที่จะทำให้คำแนะนำเหล่านั้นทันสมัยซึ่งพวกเขาไม่สามารถ
kleopatra

1
คุณรู้ไหมฉันมี "ปืนไม่ฆ่าผู้คนฆ่าผู้คน" มุมมองประเภทต่าง ๆ เหล่านี้ :) ถ้ามีคนใช้วิธีการเหล่านี้พวกเขาจำเป็นต้องตระหนักถึงสิ่งต่าง ๆ เช่นคะแนนดีที่คุณยกมาเกี่ยวกับการใช้คำแนะนำเลย์เอาต์ที่ไม่อาจคาดการณ์ได้ (ซึ่งเป็นเหตุผลว่าทำไมสถานการณ์ที่วิธีการเหล่านี้เหมาะสม
Jason C

ฉันคิดว่าการตั้งค่าขนาดที่ต้องการไม่ใช่ธงแดงขนาดใหญ่เลย ไม่ได้ตั้งค่าเป็นธงสีแดงขนาดใหญ่แทน ให้ฉันทำอย่างละเอียด เครื่องมือจัดการเลย์เอาต์ - ไม่ว่ามันจะฉลาดแค่ไหน - ไม่มีความคิดเกี่ยวกับฟังก์ชันตรรกะของวิดเจ็ต gui ตัวอย่างเช่นตัวจัดการโครงร่างไม่สามารถแยกความแตกต่างระหว่าง JTextField สำหรับการป้อนรหัสไปรษณีย์และ JTextField สำหรับการป้อนชื่อ ในทำนองเดียวกันมันไม่สามารถแยกความแตกต่างระหว่างปุ่มเครื่องมือถัดจาก JTextField หรือปุ่ม OK ขนาดใหญ่ที่ด้านล่างของแบบฟอร์ม ดังนั้นต้องมีชุดเครื่องมือที่ดีกว่าหรือต้องการคำแนะนำในการปรับขนาดใช่ไหม
Gee Bee

@GeeBee Nope นั่นเป็นตัวอย่างสำคัญของการตั้งค่าสถานะสีแดง สิ่งที่คุณควรทำคือใช้JTextField.setColumnsเพื่อตั้งค่าจำนวนคอลัมน์ซึ่งปรับขนาดที่ต้องการ หากคุณทำเช่นsetPreferredSizeนั้นคุณจะเข้ารหัสขนาดอย่างหนักซึ่งจะทำให้เลย์เอาต์ของคุณเสียหายขึ้นอยู่กับขนาดตัวอักษรของแพลตฟอร์ม นี่คือบางส่วนช่องข้อความในรูปแบบถุงตารางอยู่กับsetColumnsที่เรียกว่าเหมาะสม สำหรับปุ่มของคุณให้ใช้รูปแบบ / น้ำหนักกริดที่เหมาะสมเพื่อควบคุมขนาด
Jason C

@GeeBee และขณะนี้มีที่ทำอย่างถูกต้องแจ้งให้ทราบวิธีการที่ความกว้างของช่องข้อความจะลดลงเมื่อฉันลดขนาดตัวอักษร: i.snag.gy/ZULulh.jpg แม้การเปลี่ยนขนาดแบบอักษรได้ทันทีจะทำงานโดยอัตโนมัติแทนที่จะพูดว่าคุณต้องคำนวณความกว้างของฟิลด์ข้อความทั้งหมดใหม่และเรียก setPreferredSize อีกครั้งสำหรับแต่ละขนาดอย่างชัดเจนสิ่งที่คุณต้องทำคือยกเลิกการใช้เค้าโครงและขนาดจะปรับ
Jason C

20

หากคุณกำลังมีปัญหากับรูปแบบใน Java Swing แล้วผมสูงสามารถแนะนำ JGoodies FormLayoutให้ไว้ได้อย่างอิสระเป็นส่วนหนึ่งของรูปแบบฟรีแวร์ห้องสมุดโดย Karsten Lentzsch ที่นี่

ตัวจัดการเลย์เอาต์ที่ได้รับความนิยมอย่างมากนี้มีความยืดหยุ่นสูงมากทำให้สามารถพัฒนา Java UIs ที่ขัดเงาได้มาก

คุณจะพบเอกสาร Karsten ในที่นี่และบางเอกสารค่อนข้างดีจากคราสที่นี่


16

คนส่วนใหญ่เข้าใจวิธีการเหล่านี้ไม่ดี คุณไม่ควรละเลยวิธีการเหล่านี้อย่างแน่นอน มันขึ้นอยู่กับตัวจัดการเลย์เอาต์ถ้าพวกเขาเคารพวิธีการเหล่านี้ หน้านี้มีตารางที่แสดงให้เห็นว่าผู้จัดการรูปแบบใดเคารพวิธีใด:

http://thebadprogrammer.com/swing-layout-manager-sizing/

ฉันเขียนโค้ดสวิงมา 8 ปีแล้วและผู้จัดการโครงร่างที่รวมอยู่ใน JDK นั้นตอบสนองความต้องการของฉันเสมอ ฉันไม่เคยต้องการผู้จัดการรูปแบบบุคคลที่สามเพื่อให้บรรลุเค้าโครงของฉัน

ฉันจะบอกว่าคุณไม่ควรพยายามให้คำแนะนำตัวจัดการโครงร่างกับวิธีการเหล่านี้จนกว่าคุณจะแน่ใจว่าคุณต้องการพวกเขา ทำเลย์เอาต์ของคุณโดยไม่ให้คำแนะนำการปรับขนาด (เช่นให้ผู้จัดการเลย์เอาท์ทำงานของมัน) จากนั้นคุณสามารถทำการแก้ไขเล็กน้อยหากต้องการ


1
ไม่ว่าจะเป็นความเข้าใจผิดเล็กน้อย (ในส่วนของคุณ) หรือความเข้าใจผิด (ในส่วนของฉัน) ให้คุณเลือก :-) คุณทำซ้ำ (ที่นี่ในบล็อกของคุณในคำตอบของคุณที่เกี่ยวข้องกับ BoxLayout) ชุด XXSize ว่าสำคัญ LayoutManager เป็น (หรือไม่) สนใจใน XXSize ที่เป็นคำใบ้ขนาดเป็นอิสระเกี่ยวกับวิธีการที่จะมาเกี่ยวกับ (การคำนวณภายในโดยองค์ประกอบหรือด้วยตนเองบังคับโดยรหัสที่ใช้งาน)
kleopatra

1
ฉันไม่แน่ใจว่าฉันเข้าใจสิ่งที่คุณได้รับที่นี่ ฉันพูดถึงข้างต้นว่าวิธี XXSize () เป็นเพียงคำแนะนำ ฉันเห็นว่าไม่มีอะไรผิดปกติกับการจัดการเลย์เอาต์เล็กน้อยหากจำเป็น ในโค้ดสวิงของฉันคุณจะพบเมธอด setXXSize () เป็นครั้งคราว ไม่มาก แต่ทุกครั้งที่ฉันพบพวกเขามีความจำเป็น JComboBox และ JSpinner ต้องการคำแนะนำบ่อยๆ โดยเฉพาะอย่างยิ่ง JComboBox ที่มีประชากรหลังจากมีการรับรู้ ดูเหมือนว่าคุณจะต่อต้านการใช้วิธีการเหล่านี้และฉันไม่รู้ว่าทำไม (บางทีฉันอาจเป็นคนที่ขาดเรือในครั้งนี้ฉันเดา)
Michael

5
ไม่ใช่วิธีการที่มีคำแนะนำคุณสมบัติคือ: ส่วนประกอบควรรายงานสิ่งที่เหมาะสมสำหรับคำแนะนำทั้งหมดบางอย่าง (ตาม fi JComboBox) ไม่ได้ - ในการคืนค่า maxInteger หรือมากกว่านั้น นั่นเป็นข้อบกพร่องและควรแก้ไขโดยคอมโบ ตามนิสัยของคุณ: ให้แน่ใจว่าอยู่ไกลเมื่อผู้ดูแลรักษาต้องทำความสะอาดให้ดีขึ้น :) คำแนะนำที่ใช้รหัสยากมีแนวโน้มที่จะทำลายรูปแบบที่มีการเปลี่ยนแปลงเล็กน้อยและยากที่จะตรวจจับว่าเป็นสาเหตุของรูปแบบที่แตกหัก
kleopatra

15

ในสถานการณ์ที่ฉันต้องการกำหนดสัดส่วนระหว่างชายด์ของคอมโพเนนต์ (ชายน์ 1 ควรใช้พื้นที่ 10%, ชาย 2 40%, เด็ก 3 50%) เป็นไปได้ไหมที่จะบรรลุเป้าหมายดังกล่าวโดยไม่ต้องใช้ตัวจัดการเลย์เอาต์แบบกำหนดเอง?

อาจGridBagLayoutจะตอบสนองความต้องการของคุณ นอกจากนั้นยังมีผู้จัดการเลย์เอาต์มากมายในเว็บและฉันพนันได้เลยว่ามีผู้จัดการเลย์เอาต์ที่เหมาะกับความต้องการของคุณ


ขอบคุณสำหรับคำตอบ. ฉันต้องสมมติว่าคุณหมายถึง: "อย่าใช้ setPreferredSize เลย" ใช่ไหม
Heisenbug

1
GridBagLayout ใช้ข้อ จำกัด ซึ่งคุณสามารถระบุ "น้ำหนัก" ทั้งใน X และ Y สำหรับองค์ประกอบที่กำหนดดังนั้น LayoutManager สามารถตัดสินใจว่าจะทำอย่างไรกับพื้นที่พิเศษในการปรับขนาด แต่คุณยังคงต้องการ / สามารถใช้ setPreferredSize เพื่อกำหนดขนาดที่ต้องการของแต่ละองค์ประกอบโปรดทราบว่า "ที่ต้องการ" ไม่ได้หมายความว่ามันจะได้รับเกียรติเสมอ สำหรับกรณีพิเศษคุณอาจต้องใช้ setMinimumSize และ setMaximumSize ต่อไป พวกเขาไม่ใช่คนชั่วไม่ซื้อมัน docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
マルルちゃんだよよ

5

ฉันเห็นว่ามันแตกต่างจากคำตอบที่ยอมรับ

1) ฉันควรหลีกเลี่ยงการใช้วิธีการเหล่านั้นอย่างสมบูรณ์หรือไม่?

ไม่เคยหลีกเลี่ยง! พวกเขาอยู่ที่นั่นเพื่อแสดงข้อ จำกัด ขนาดของส่วนประกอบของคุณไปยังผู้จัดการรูปแบบ คุณสามารถหลีกเลี่ยงการใช้สิ่งเหล่านี้ได้หากคุณไม่ได้ใช้ตัวจัดการเลย์เอาท์ใด ๆ และพยายามที่จะจัดการเลย์เอาต์ภาพด้วยตัวคุณเอง

น่าเสียดายที่ Swing ไม่ได้มาพร้อมขนาดเริ่มต้นที่เหมาะสม อย่างไรก็ตามแทนที่จะตั้งค่าขนาดขององค์ประกอบเป็น OOP ที่ดีกว่าเพื่อสืบส่วนประกอบของคุณเองด้วยค่าเริ่มต้นที่เหมาะสม (ในกรณีนี้คุณเรียก setXXX ในคลาสที่สืบทอด) หรืออีกวิธีหนึ่งคุณสามารถแทนที่เมธอด getXXX สำหรับเอฟเฟกต์เดียวกัน

2) มีการกำหนดวิธีการด้วยเหตุผล ดังนั้นเมื่อไรฉันจึงควรใช้ ในบริบทใด มีวัตถุประสงค์อะไร?

เสมอ. เมื่อคุณสร้างส่วนประกอบให้ตั้งค่าขนาด min / Preferred / max ที่เหมือนจริงตามการใช้งานของส่วนประกอบนั้น ตัวอย่างเช่นหากคุณมี JTextField สำหรับการป้อนสัญลักษณ์ประเทศเช่นสหราชอาณาจักรขนาดที่ต้องการจะต้องกว้างพอที่จะใส่ตัวอักษรสองตัว (ด้วยตัวอักษรปัจจุบัน ฯลฯ ) แต่อาจไม่มีความหมายที่จะทำให้มันใหญ่ขึ้น ท้ายที่สุดแล้วสัญลักษณ์ประเทศเป็นสองตัวอักษร ตรงกันข้ามถ้าคุณมี JTextField สำหรับป้อนเช่นชื่อลูกค้าสามารถมีขนาดที่ต้องการเช่นขนาดพิกเซล 20 ตัวอักษร แต่สามารถขยายให้ใหญ่ขึ้นได้หากปรับขนาดเลย์เอาท์ดังนั้นกำหนดขนาดสูงสุดเป็นเพิ่มเติม ในขณะเดียวกันการมี JTextField กว้าง 0px นั้นไม่มีจุดหมายดังนั้นให้ตั้งขนาดขั้นต่ำที่เหมือนจริง

3) อะไรคือผลกระทบเชิงลบจากการใช้วิธีการเหล่านั้น?

(ฉันคิดได้แค่เพิ่มความสะดวกในการพกพาระหว่างระบบที่มีความละเอียดหน้าจอต่างกัน)

ไม่มีผลกระทบเชิงลบ สิ่งเหล่านี้เป็นคำแนะนำสำหรับผู้จัดการโครงร่าง

4) ฉันไม่คิดว่า LayoutManager ใด ๆ สามารถตอบสนองทุกรูปแบบที่ต้องการได้อย่างแท้จริง

ฉันจำเป็นต้องใช้ LayoutManager ใหม่สำหรับรูปแบบเล็ก ๆ น้อย ๆ ทุกรูปแบบหรือไม่

ไม่ไม่แน่นอน วิธีการตามปกติคือการจัดเรียงเค้าโครงขั้นพื้นฐานที่แตกต่างกันเช่นเค้าโครงแนวนอนและแนวตั้ง

ตัวอย่างเช่นรูปแบบด้านล่าง:

<pre>
+--------------+--------+
| ###JTABLE### | [Add]  | 
| ...data...   |[Remove]|
| ...data...   |        |
| ...data...   |        |
+--------------+--------+
</pre>

กำลังมีสองส่วน ส่วนซ้ายและขวาเป็นเค้าโครงแนวนอน ส่วนที่ถูกต้องคือ JPanel ที่เพิ่มเข้าไปในเค้าโครงแนวนอนและ JPanel นี้มีรูปแบบแนวตั้งที่วางปุ่มในแนวตั้ง

แน่นอนว่าสิ่งนี้สามารถเติบโตได้ยากด้วยเค้าโครงชีวิตจริง ดังนั้นตัวจัดการโครงร่างแบบกริดเช่น MigLayout จะดีกว่ามากถ้าคุณกำลังจะพัฒนาสิ่งที่ร้ายแรง

5) ถ้าคำตอบที่ 4 คือ "ใช่" สิ่งนี้จะนำไปสู่การเพิ่มจำนวนคลาส LayoutManager ซึ่งจะยากต่อการรักษาหรือไม่?

ไม่แน่นอนคุณจะไม่พัฒนาผู้จัดการเลย์เอาท์เว้นแต่คุณต้องการบางสิ่งที่พิเศษมาก

6) ในสถานการณ์ที่ฉันต้องกำหนดสัดส่วน ...

ระหว่างชายด์ของ Component (เช่น child1 ควรใช้ 10% ของ space, child2 40%, child3 50%) เป็นไปได้หรือไม่ที่จะบรรลุโดยไม่ต้องใช้ LayoutManager ที่กำหนดเอง?

โดยทั่วไปเมื่อตั้งค่าขนาดที่ต้องการแล้วคุณอาจไม่ต้องการทำอะไรเป็นเปอร์เซ็นต์ เนื่องจากเปอร์เซ็นต์นั้นไม่มีจุดหมาย (เช่นไม่มีจุดหมายที่จะมี JTextField 10% ของขนาดหน้าต่าง - เนื่องจากสามารถย่อขนาดหน้าต่างเพื่อให้ JTextField กลายเป็นความกว้าง 0px หรือสามารถขยายหน้าต่างเพื่อให้ JTextField ข้ามจอแสดงผลสองจอบนหน้าจอเดียว ตั้งค่าการแสดงผลหลายจอ)

แต่บางครั้งคุณอาจใช้เปอร์เซ็นต์เพื่อควบคุมขนาดของหน่วยการสร้างที่ใหญ่กว่าของ gui ของคุณ (ตัวอย่างเช่นพาเนล)

คุณสามารถใช้ JSplitPane ซึ่งคุณสามารถกำหนดอัตราส่วนของทั้งสองด้านล่วงหน้าได้ หรือคุณสามารถใช้ MigLayout ซึ่งอนุญาตให้คุณตั้งค่าข้อ จำกัด ดังกล่าวเป็นเปอร์เซ็นต์พิกเซลและหน่วยอื่น ๆ


จริงๆ? นี่คือที่ 0? นี่ดีกว่าคำตอบที่ยอมรับได้ที่มี 100+ อัพ ที่โดยทั่วไปกล่าวว่า "เจ้าจะใช้ nevar setPreferredSize!" ซึ่งเป็น TERRIBLE ในสายงานของฉันมีข้อกำหนดขนาดเฉพาะจำนวนมากเช่น "ปุ่มบนหน้าจอสัมผัสต้องเป็น [X] โดย [Y] กับ [M] x [N] ระยะห่างระหว่าง" ข้อกำหนดด้านความปลอดภัย btnBar.setPreferredSize( dimTouchBtn );เป็นวิธีที่ดีที่สุดในการทำเช่นนั้น ตรงไปตรงมาไม่จำเป็นต้องใช้ตัวจัดการเค้าโครงที่กำหนดเอง ฉันใช้ส่วนใหญ่GridBagLayoutกับบางBorderLayoutและBoxLayoutรังเมื่อสะดวก นี่คือการรวมกันที่แข็งแกร่งและใช้งานง่าย
Loduwijk

ฉันรีบร้อนในความคิดเห็นข้างต้นของฉัน นี่เป็นคำตอบแรกที่ฉันเห็นหลังจากคำตอบที่ยอมรับ เหตุใดจึงไม่เรียงลำดับตามการโหวตอีกต่อไป ฉันคิดว่านั่นเป็นหนึ่งในเหตุผลหลักในการนับคะแนน ฉันยังคงยืนแสดงความคิดเห็นต้นฉบับอย่างไรก็ตาม; นี่เป็นหนึ่งในคำตอบที่ดีกว่า ยกเว้นจุดที่ # 6 - สิ่งนั้นไม่ยอดเยี่ยม มีเหตุผลมากมาย (ชนกลุ่มน้อยที่ยังสามารถเป็นจำนวนมาก) และ GridBagLayout สนับสนุนที่ดีในกรณีส่วนใหญ่ที่ฉันเคยมี
Loduwijk

ฉันคิดว่าการปรับขนาดและไม่ปรับขนาดจะไม่ถือว่าเป็นการตัดสินใจทางศาสนา มีกรณีใช้เมื่อไม่มีใครต้องการปรับขนาดอะไรเช่นถ้าคุณพัฒนา GUI สำหรับตู้ด้วยความละเอียดคงที่ที่กำหนดไว้ล่วงหน้า หากคุณมีเป้าหมายที่แตกต่างกันเช่นจอภาพ HMI แบบอุตสาหกรรมและตัวพิมพ์ "ปุ่ม" ใช่คุณต้องมีอย่างน้อย 1 ซม. โดย 1 ซม. สำหรับปุ่มบนหน้าจอสัมผัส ในกรณีนี้ DPI ของหน้าจอจะกำหนดวิธีการปรับขนาด อินพุตอื่น ๆ เช่นฟิลด์ข้อความอาจไม่ได้รับการปรับขนาดในแนวตั้งเลยและบางครั้ง (เช่นรหัสไปรษณีย์) การปรับขนาดแนวนอนก็ไม่มีประโยชน์เช่นกัน
Gee Bee

0

ฉันควรหลีกเลี่ยงการใช้วิธีการเหล่านั้นอย่างสมบูรณ์หรือไม่? ฉันจะไม่พูดว่า "หลีกเลี่ยง" พวกเขา ฉันจะบอกว่าถ้าคุณคิดว่าคุณต้องการพวกเขาคุณอาจทำอะไรผิด ขนาดส่วนประกอบถูกกำหนดในบริบท ตัวอย่างเช่นขนาดองค์ประกอบข้อความจะถูกกำหนดโดยจำนวนแถวและคอลัมน์ที่คุณระบุรวมกับแบบอักษรที่คุณอาจเลือก ปุ่มและขนาดป้ายกำกับของคุณจะเป็นขนาดของกราฟิกถ้าคุณตั้งค่าหนึ่งหรือพื้นที่ที่จำเป็นในการแสดงข้อความที่คุณกำหนด แต่ละองค์ประกอบมีขนาดที่เป็นธรรมชาติและผู้จัดการโครงร่างจะใช้องค์ประกอบเหล่านั้นเพื่อจัดวางทุกอย่างโดยที่คุณไม่จำเป็นต้องระบุขนาด ข้อยกเว้นหลักคือ JScrollPane ซึ่งมีขนาดเป็นอิสระจากสิ่งที่มันมี สำหรับบางครั้งฉันจะโทรsetSize()และให้ขนาดนั้นกำหนดขนาดหน้าต่างเริ่มต้นโดยการโทรJFrame.pack(). โดยปกติฉันจะให้ขนาดหน้าต่างกำหนดขนาด JScrollPane ผู้ใช้จะเป็นผู้กำหนดขนาดของหน้าต่าง ผู้จัดการเลย์เอาต์หลายคนเพิกเฉยกับขนาดที่คุณตั้งไว้ดังนั้นบ่อยครั้งที่พวกเขาทำสิ่งที่ไม่ค่อยดี

มีการกำหนดวิธีการด้วยเหตุผล ดังนั้นเมื่อไรฉันจึงควรใช้ ในบริบทใด มีวัตถุประสงค์อะไร? ฉันเชื่อว่าพวกเขาถูกเพิ่มเข้ามาเพื่อให้คำแนะนำแก่ผู้จัดการโครงร่าง พวกเขาอาจถูกเขียนด้วยเหตุผลทางประวัติศาสตร์เพราะผู้จัดการเลย์เอาท์ใหม่และผู้คนไม่ไว้วางใจพวกเขาอย่างเต็มที่ ฉันรู้ว่านักพัฒนาไม่กี่คนที่หลีกเลี่ยงผู้จัดการเลย์เอาท์และวางทุกอย่างด้วยตนเองเพียงเพราะพวกเขาไม่ต้องการยุ่งกับการเรียนรู้กระบวนทัศน์ใหม่ มันเป็นความคิดที่แย่มาก

อะไรคือผลกระทบด้านลบจากการใช้วิธีการเหล่านั้น? (ฉันคิดได้แค่เพิ่มความสะดวกในการพกพาระหว่างระบบที่มีความละเอียดหน้าจอต่างกัน) พวกมันไม่มีประสิทธิภาพและพวกมันสร้างเลย์เอาท์ที่ไม่ดีโดยวัตถุจะถูกบีบหรือยืดให้มีขนาดที่ไม่เป็นธรรมชาติ และเลย์เอาท์จะเปราะ การเปลี่ยนแปลงขนาดหน้าต่างบางครั้งจะทำให้เลย์เอาต์เสียหายและวางสิ่งผิดที่

ฉันไม่คิดว่า LayoutManager ใด ๆ สามารถตอบสนองทุกรูปแบบที่ต้องการได้อย่างแท้จริง ฉันจำเป็นต้องใช้ LayoutManager ใหม่สำหรับรูปแบบเล็ก ๆ น้อย ๆ ทุกรูปแบบหรือไม่ คุณไม่ควร "ใช้งาน" LayoutManager ใหม่ คุณควรยกตัวอย่างสิ่งที่มีอยู่ ฉันมักจะใช้ตัวจัดการรูปแบบหลายตัวในหน้าต่างเดียว JPanel แต่ละคนจะมีผู้จัดการเลย์เอาต์ของตัวเอง บางคนหยุดชะงักที่เลย์เอาต์ที่ซ้อนกันเพราะมันยากที่จะรักษา เมื่อฉันใช้มันฉันให้วิธีการสร้างของแต่ละคนเพื่อให้ง่ายต่อการดูว่าแต่ละคนทำอะไร แต่ฉันไม่เคย "ใช้งาน" เครื่องมือจัดการโครงร่าง ฉันแค่ยกตัวอย่างพวกเขา

หากคำตอบของ 4 คือ "ใช่" สิ่งนี้จะนำไปสู่การเพิ่มจำนวนคลาส LayoutManager ซึ่งจะยากต่อการรักษาหรือไม่? หากคุณกำลังใช้คลาสตัวจัดการโครงร่างใหม่สำหรับรูปแบบที่เปลี่ยนแปลงเล็กน้อยคุณจะใช้ผิดประเภท หากคุณเพิ่งใช้งานผู้จัดการเลย์เอาต์ใหม่คุณอาจทำผิดพลาด ครั้งเดียวที่ฉันขยายคลาส LayoutManager มันคือการเพิ่มตัวเลื่อนการซูมไปยัง JScrollPane

ในสถานการณ์ที่ฉันต้องกำหนดสัดส่วนระหว่างลูกของ Component (เช่น child1 ควรใช้พื้นที่ 10%, child2 40%, child3 50%) เป็นไปได้หรือไม่ที่จะใช้ LayoutManager แบบกำหนดเองได้? JSplitPane มีวิธีระบุเปอร์เซ็นต์ที่แต่ละองค์ประกอบควรได้รับ ตัวหารสามารถเคลื่อนย้ายได้ตามค่าเริ่มต้น แต่คุณสามารถปิดการใช้งานได้หากคุณต้องการ ฉันไม่ได้ใช้คุณสมบัตินี้มากนัก ฉันมักจะมีส่วนประกอบบางอย่างที่ใช้ขนาดที่กำหนดและพื้นที่ที่เหลือถูกถ่ายโดยบานหน้าต่างเลื่อน ขนาดบานหน้าต่างเลื่อนจะปรับตามขนาดหน้าต่าง หากคุณมีบานหน้าต่างเลื่อนสองบานอยู่ข้างๆกันคุณสามารถวางไว้ใน JSplitPane และระบุเปอร์เซ็นต์ของพื้นที่ใหม่ที่กำหนดให้แต่ละอันขณะที่ผู้ใช้ขยายและหดหน้าต่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.