لماذا لا يتم عرض المكون الجديد في مدير تخطيط فارغ؟

StackOverflow https://stackoverflow.com/questions/3701844

  •  02-10-2019
  •  | 
  •  

سؤال

هناك لوحة في أ JFrame يسمى ب WatchPanel extends JPanel الذي يستخدم GroupLayout ويحتوي على أ WatchListPanel extends JPanel. ال WatchListPanel يستخدم null LayoutManager ويحتوي على عدة حالات WatchItemPanel extends JPanel. ال WatchItemPanel يضع محتوياته مع GridBagLayout.

عندما أقوم بتحميل الإطار وتثبيت WatchPanel, ، أنا مسبق تحميل WatchListPanel مع ثلاثة WatchItemPanel مثيلات مع البيانات. هذه تعمل بشكل جيد. يسمح تنفيذي بإعادة ترتيبها عن طريق السحب والإسقاط (ومن هنا جاء null التصميم) ، وهذا يعمل كذلك. على ال WatchPanel هو زر لإضافة ساعة جديدة ، تنبثق لوحة جديدة بمفردها JFrame حيث يمكن إضافة ساعة. عند الضغط على زر "حفظ" على هذه اللوحة الجديدة ، فإنه يضيف الساعة الجديدة إلى WatchPanel, ، الذي يتدفق إلى WatchListPanel ويغلق JFrame لإضافة ساعة جديدة.

المشكلة هي أنه عندما هذا جديد WatchItemPanel يضاف ، لا يتم رسمه إلا إذا قمت بتغيير حجم JFrame تحتوي على WatchPanel. يمكنني التفاعل معها من خلال drag-n-drop. يمكنني حتى سحب تلك اللوحة المحددة - لكنها فارغة. في اللحظة التي أقوم بتغيير حجمها WatchPanel, ، يبدو ومرسم بشكل صحيح.

الآن ، لقد تجاوزت setBounds طريقة على WatchListPanel للإتصال setSize و repaint على كل من WatchItemPanel مثيلات في القائمة ، لكنني أتصل setBounds و repaint على الجديد WatchItemPanel بالفعل كما أضيفه. لقد حاولت إضافة repaint و invalidate مكالمات في كل مكان يمكن تصوره ، ربما فاتني شيء ، لكن لا حظ. لقد أضفت بالتأكيد WatchItemPanel إلى WatchListPanel ودعا setBounds, setVisible(true), ، و repaint على اللوحة الجديدة.

ها هي addWatch و updatePositions طرق على WatchListPanel:

public void addWatch(Watch watch) {
    WatchItemPanel watchPanel = new WatchItemPanel(watch);
    synchronized (this.watches) {
        this.watches.add(watch);
    }
    this.watchPanels.put(watch, watchPanel);
    this.add(watchPanel);
    watchPanel.setOpaque(false);
    watchPanel.setForeground(this.getForeground());
    watchPanel.setBackground(this.getBackground());
    watchPanel.setVisible(true);
    watchPanel.setSize(this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    for (MouseListener l: this.mouseListeners)
        watchPanel.addMouseListener(l);
    for (MouseMotionListener l: this.mouseMotionListeners)
        watchPanel.addMouseMotionListener(l);
    this.updatePositions();
}

private void updatePositions() {
    int count = 0;
    synchronized (this.watches) {
        for (Watch watch: this.watches) {
            if ((this.selectedWatchPanel != null) && (count == this.selectedWatchPanelPosition))
                count++;
            WatchItemPanel panel = this.watchPanels.get(watch);
            if (panel == this.selectedWatchPanel)
                continue;
            panel.setBounds(0, count * WatchItemPanel.PANEL_HEIGHT, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
            count++;
        }
    }
    if (this.selectedWatchPanel != null)
        this.selectedWatchPanel.setBounds(0, (this.selectedWatchPanelPosition * WatchItemPanel.PANEL_HEIGHT) + this.selectedWatchPanelDragOffset, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    this.repaint();
}

وهنا setBounds طرق على WatchListPanel:

@Override
public void setBounds(Rectangle r) {
    super.setBounds(r);
    for (WatchItemPanel panel: this.watchPanels.values()) {
        panel.setSize(r.width, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

@Override
public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x, y, width, height);
    for (WatchItemPanel panel: this.watchPanels.values()) {
        panel.setSize(width, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

جزء آخر من المعلومات هنا - يتم رسم جميع اللوحات الأربعة. لقد تجاوزت paintComponent في ال WatchItemPanel وأضاف أ System.out.println وحصلت على هذه النتيجة:

WatchItemPanel[,0,66,366x22,invalid,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,44,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,22,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,0,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]

ما هو هذا العمود "غير صالح" الإضافي في اللوحة؟ عندما أقوم بتغيير حجم WatchPanel "غير صالح" يذهب بعيدا. يبدو وكأنه عمود إضافي ، على الرغم من. لا توجد قيمة غير مقابلة على الخطوط الأخرى. (هذا هو الافتراضي JPanel.toString() الإخراج مع إزالة اسم الحزمة.

هل كانت مفيدة؟

المحلول

بعد إضافة المكون ، اتصل this.revalidate(). هذا يتسبب في تمييز الحاوية لإعادة وضع مكوناتها. بمجرد إضافة هذا السطر من التعليمات البرمجية ، فإنه يعمل بشكل مثالي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top