JComponent.setBounds JComponent สุดท้ายในตำแหน่งที่ไม่ถูกต้อง

ฉันมีปัญหาบางอย่างกับ Swing เมื่อเร็ว ๆ นี้ ฉันกำลังพยายามสร้างสิ่งที่เหมือนในภาพด้านล่างทันที เพื่อแสดงโครงสร้างข้อมูลสำหรับอัลกอริธึม

ภาพโน้ตบุ๊ก
(ที่มา: ius.edu)

สิ่งที่ฉันพยายามทำในชั้นเรียนต่อไปนี้คือวาดรูปสี่เหลี่ยมที่มีตัวเลขอยู่ และแปลพวกมัน แต่สี่เหลี่ยมสุดท้ายจะดึงที่ 0,0 ฉันนิ่งงัน.

หากคุณเพิ่ม JPanel (ใส่เครื่องหมายความคิดเห็น) หลังลูป มันจะดึงตามที่คาดไว้

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class DrawingRect {

    public static void main(String[] args) {
        DrawingRect d = new DrawingRect();
    }

    public DrawingRect() {

        JFrame frame = new JFrame("Drawing a rect");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel swingPanel = new JPanel();
        swingPanel.setPreferredSize(new Dimension(500, 500));

        swingPanel.setVisible(true);

        swingPanel.setLayout(new BorderLayout(0, 0));

        int base = 15;
        for (int i = 1; i <= 25; i++) {
            Graphic re = new Graphic(i);

            //translating the graphic
            re.setBounds(base + 30 * i, base + 20 * i, 110, 110);


            swingPanel.add(re);
        }


        // if say I add a JPanel in here as the last element
        // then the boxes will draw correctly.
        //swingPanel.add(new JPanel());

        swingPanel.setPreferredSize(new Dimension(800, 600));

        frame.getContentPane().add(swingPanel);

        frame.pack();
        frame.setVisible(true);
    }

    public class Graphic extends JComponent {

        private static final long serialVersionUID = 1L;
        private static final int PREF_W = 100;
        private static final int PREF_H = 100;
        int id;

        public Graphic(int id) {
            this.id = id;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.black);

            g2.setColor(Color.black);
            g2.drawRoundRect(0, 0, 30, 30, 20, 20);

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

            Font font = new Font("", Font.PLAIN, 13);
            g2.setFont(font);

            g2.drawString("" + id, 15, 20);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(PREF_W, PREF_H);
        }
    }
}   

person Andrew    schedule 13.04.2012    source แหล่งที่มา


คำตอบ (2)


เลย์เอาต์ เริ่มต้นของ JPanel คือ FlowLayout แต่คุณ การวางตำแหน่งส่วนประกอบราวกับว่าเค้าโครงเป็น null นอกจากนี้ คุณกำลังวาดเนื้อหาที่ส่วนประกอบที่ซ้อนกันสามารถทำได้โดยอัตโนมัติ

ให้เพิ่ม JPanel หลายอันที่มี JLabel ลงในแผงที่มี GridLayout แทน ใช้แผงเปล่าตามต้องการ แทนที่ paintComponent() ในแผงด้านนอกเพื่อวาดเส้นเชื่อมต่อ

ภาคผนวก: เมื่อใดก็ตามที่มีคนอยากใช้ Absolute Positioning, JInternalFrame อาจเป็นทางเลือก ตัวอย่างที่เกี่ยวข้องอาจพบได้ที่นี่ และที่นี่

ภาคผนวก: หากโปรเจ็กต์เติบโตเกินกว่าระยะต้นแบบ ให้พิจารณา เครื่องมือจัดการเลย์เอาต์แบบกำหนดเอง

person trashgod    schedule 13.04.2012
comment
ขอบคุณการตั้งค่าเลย์เอาต์เป็นโมฆะทำให้ฉันได้ผลลัพธ์ตามที่ต้องการ แต่ฉันยังคงใช้ JPanel อยู่ - person Andrew; 14.04.2012

เป็นเพราะคุณกำลังใช้ BorderLayout คุณสามารถทดสอบได้โดยเปลี่ยนบรรทัดเพิ่มของคุณเพื่อรวมตำแหน่งเค้าโครงเฉพาะ: swingPanel.add(re,BorderLayout.SOUTH)

สำหรับวิธีแก้ปัญหา ทำไมไม่วาดรูปสี่เหลี่ยมทั้งหมดบนรูปภาพแล้วอัปเดตที่ส่วนท้ายของลูปล่ะ หรือการเพิ่ม JPanel เป็นส่วนหนึ่งของการสาธิตของคุณ?

person Youssef G.    schedule 13.04.2012
comment
frame มี BorderLayout เป็นค่าเริ่มต้น แต่ swingPanel et infra มีค่าเริ่มต้น FlowLayout +1 สำหรับการแนะนำองค์ประกอบนอกจอ - person trashgod; 14.04.2012
comment
@trashgod คุณช่วยอธิบายได้ไหมว่าเฟรมนั้นเป็นเฟรมที่มี Borderlayout และ Panel เป็นเฟรมที่มี FlowLayout อย่างไร ฉันไม่เห็นเค้าโครงที่ถูกตั้งค่าบน Frame ดังนั้นฉันจึงถือว่ามันมีเค้าโครงเริ่มต้น แต่ swingPanel ถูกกำหนดเป็น BorderLayout อย่างชัดเจน การเปลี่ยนแปลงหรือการลบ swingPanel.setLayout(new BorderLayout()); จะแสดงโครงร่างโฟลว์ที่คาดหวังโดยที่ทุกอย่างอยู่ในแถวและตัดเป็นแถวใหม่เมื่อไม่มีที่ว่างอีกต่อไป - person Youssef G.; 14.04.2012
comment
อ๊ะ ข้อผิดพลาดของฉัน การวิเคราะห์ของคุณถูกต้อง ฉันมุ่งเน้นไปที่ตัวสร้าง no-arg new JPanel() และมองข้าม setLayout() ที่ตามมา ขอบคุณสำหรับการชี้แจง - person trashgod; 14.04.2012