سؤال

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

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

المحلول

ما تحتاجه هو:

  • طريقة لنمذجة "عمر" الصف في نموذج الجدول الخاص بك.من الأفضل القيام بذلك بشكل ضمني، لذلك تقوم فقط بتخزين وقت إنشاء الصف مرة واحدة وحساب العمر عند طلب قيمة الخلية (Object getValueAt(row, column)).
  • خيط (خفي) يطلق حدث تغيير الجدول كل ثانية.لا يتعين عليك إطلاق حدث واحد في كل صف، ولكن بدلاً من ذلك يمكنك إطلاق حدث يشير إلى تحديث عمود كامل.

إليك بعض الكود الكاذب لنموذج الجدول:

public Object getValueAt (int rowIndex, int columnIndex) {

    // if it's the column with the 'row age', calculate the age and return it
    long rowAgeMs = System.currentTimeMs() - getCreationTime(rowIndex);

   // return the age in milliseconds, or a date, or a formatted time string 
}

يجب أن يقدم نموذج الجدول أيضًا طريقة للسلسلة، حتى يتمكن من إطلاق حدث تغيير لعمود "عمر الصف":

الطبقة العامة MyTableModel تنفذ TableModel {

   private final List<TableModelListener> listeners = new LinkedList<TableModelListener>();

   public void addTableModelListener (TableModelListener l) {
          listeners.add(l);
   }

   public void removeTableModelListener (TableModelListener l) {
          listeners.remove(l);
   }

   public void updateColumn (int column) {
          TableModelEvent evt = new TableModelEvent(this, 0, Math.max(0, getRowCount() - 1), column);
          for (TableModelListener listener : listeners) {
                 listener.tableChanged(evt);
          }
   }

سيقوم مؤشر الترابط بعد ذلك بتشغيل طريقة updateColumn(..) كل ثانية لعمود "عمر الصف".يجب أن يتم استدعاء هذه الطريقة في EventDispatchThread، ويتم ذلك باستخدام SwingUtilities.invocayAndWait(..) أو SwingUtilities.invocLater(..).

Thread rowAgeUpdater = new Thread() {

        @Override
        public void run () {
            while (isAlive()) {
                try {

                    long time = System.currentTimeMillis();
                    long sleepTime = (time / 1000 + 1) * 1000 - time;
                    Thread.sleep(sleepTime);

                    SwingUtilities.invokeAndWait(new Runnable() {
                        public void run () {
                            model.updateColumn(ROW_AGE_COLUMN_INDEX);
                        }
                    });

                } catch (Exception e) {
                    return;
                }

            }
        }
    };
    rowAgeUpdater.setDaemon(true);
    rowAgeUpdater.setPriority(Thread.MIN_PRIORITY);
    rowAgeUpdater.start();

طالما أن دقة TableModelEvent تغطي فقط الخلايا التي تحتاج إلى التحديث (في حالتك:فقط العمود الذي يحتوي على عمر الصف)، إنها الطريقة الأكثر فعالية لتحقيق ذلك.

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