JComponent.setMembatasi JComponent terakhir di tempat yang salah

Saya mengalami beberapa masalah dengan Swing akhir-akhir ini. Saya mencoba membuat sesuatu seperti pada gambar di bawah ini dengan cepat, untuk mengilustrasikan struktur data untuk algoritma.

gambar buku catatan
(sumber: ius.edu)

Semua yang saya coba lakukan di kelas berikut adalah menggambar beberapa persegi panjang dengan angka di atasnya. dan terjemahkan, namun persegi panjang terakhir berada pada 0,0. saya bingung.

Jika Anda menambahkan JPanel (berkomentar) setelah loop maka itu akan ditarik seperti yang diharapkan.

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 sumber


Jawaban (2)


tata letak default dari JPanel adalah FlowLayout, tetapi Anda memposisikan komponen seolah-olah tata letaknya adalah null. Selain itu, Anda menggambar konten yang dapat dilakukan oleh komponen bersarang secara otomatis.

Sebagai gantinya, tambahkan beberapa JPanel yang berisi JLabel ke panel berisi GridLayout. Gunakan panel kosong sesuai kebutuhan. Ganti paintComponent() di panel luar untuk menggambar garis penghubung.

Tambahan: Kapan pun seseorang tergoda untuk menggunakan Pemosisian Absolut, JInternalFrame mungkin bisa menjadi alternatif. Contoh terkait dapat ditemukan di sini dan di sini.

Tambahan: Jika proyek berkembang melampaui tahap prototipe, pertimbangkan juga Manajer Tata Letak Khusus.

person trashgod    schedule 13.04.2012
comment
Terima kasih mengatur tata letak ke null memberi saya hasil yang saya cari, namun saya masih menggunakan JPanel. - person Andrew; 14.04.2012

Itu karena Anda menggunakan BorderLayout. Anda dapat mengujinya dengan mengubah baris tambahan untuk menyertakan lokasi tata letak tertentu: swingPanel.add(re,BorderLayout.SOUTH).

Adapun solusinya, mengapa tidak menggambar semua persegi panjang pada gambar dan memperbaruinya di akhir perulangan? Atau apakah penambahan JPanel merupakan bagian dari demonstrasi Anda?

person Youssef G.    schedule 13.04.2012
comment
frame memiliki BorderLayout secara default, namun swingPanel dan infra memiliki default FlowLayout. +1 untuk menyarankan komposisi di luar layar. - person trashgod; 14.04.2012
comment
@trashgod, bisakah Anda menjelaskan bagaimana framenya yang memiliki Borderlayout dan Panelnya yang memiliki FlowLayout? Saya tidak melihat tata letak disetel pada Bingkai, jadi saya berasumsi itu memiliki tata letak default, tetapi swingPanel jelas disetel ke BorderLayout. Mengubah atau menghapus swingPanel.setLayout(new BorderLayout()); menunjukkan tata letak aliran yang diharapkan di mana semuanya berada dalam satu baris dan digabungkan ke baris baru ketika tidak ada lagi ruang yang tersedia. - person Youssef G.; 14.04.2012
comment
Ups, kesalahan saya; analisis Anda benar. Saya fokus pada konstruktor no-arg new JPanel() dan mengabaikan setLayout() berikutnya. Terima kasih telah menjelaskan. - person trashgod; 14.04.2012