لماذا لا يتم عرض المكون الجديد في مدير تخطيط فارغ؟
-
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()
. هذا يتسبب في تمييز الحاوية لإعادة وضع مكوناتها. بمجرد إضافة هذا السطر من التعليمات البرمجية ، فإنه يعمل بشكل مثالي.