2011-11-11 17 views
5

मैं Java TableModelListener and Live Feed Listener? का उत्तर पोस्ट प्राप्त करने में सूचक बदलने के लिए, लेकिन मैं से एक टिप्पणी प्राप्त - somone कर सकते हैं मुझे समझाने के लिए क्या की एक घटना बदलें प्राप्त करने में सूचक बदलें Kleopatraक्यों कभी नहीं एक परिवर्तन घटना

nonono - you never change the notifier in receiving a change event. 
As to probable effects, think: nasty loops. As to code sanity, think: 
indecent intimacy. It's the task of the model itself to internally 
update related values if necessary. 

, क्या हो, क्या वह वास्तव मतलब है, क्योंकि वह मुझे पता है कि मैं केवल बहुत जल्दी पाश से RepaintManager अपवाद प्राप्त करने के रूप मैं सब कुछ करने की कोशिश की हो सकती है,

मैं एक अपवाद कभी नहीं मिलता है, जहां

  • मैं multiplaeyd कि 50 x 1000 मैट्रिक्स के लिए,

  • prepareRenderer साथ

    (possitive/नकारात्मक मूल्य के लिए बदलने के रंग)

  • ताज़ा दर के साथ

    175 मिलीसेकंड

कोड को बदलने का प्रदर्शन किया नोटिफायर और दो अन्य (शायद सही) तरीका कैसे

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.util.Random; 
import java.util.concurrent.*; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.table.DefaultTableModel; 

public class ChangeNotifiersOnEvent extends JFrame implements Runnable { 

    private static final long serialVersionUID = 1L; 
    private boolean runProcess = true; 
    private Random random = new Random(); 
    private javax.swing.Timer timerRun; 
    private Executor executor = Executors.newCachedThreadPool(); 
    private String[] columnNames = {"Source", "Hit", "Last", "Ur_Diff"}; 
    private JTable table; 
    private Object[][] data = {{"Swing Timer", 2.99, 5, 1.01}, 
     {"Swing Worker", 7.10, 5, 1.010}, {"TableModelListener", 25.05, 5, 1.01}}; 
    private DefaultTableModel model = new DefaultTableModel(data, columnNames); 

    public ChangeNotifiersOnEvent() { 
     table = new JTable(model) { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public Class getColumnClass(int column) { 
       return getValueAt(0, column).getClass(); 
      } 
     }; 
     model.addTableModelListener(new TableModelListener() { 

      @Override 
      public void tableChanged(TableModelEvent tme) { 
       if (tme.getType() == TableModelEvent.UPDATE) { 
        if (tme.getColumn() == 1 && tme.getLastRow() == 2) { 
         double dbl = ((Double) table.getModel().getValueAt(2, 1)) 
           - ((Integer) table.getModel().getValueAt(2, 2)); 
         table.getModel().setValueAt(dbl, 2, 3); 
        } else if (tme.getColumn() == 1 && tme.getLastRow() == 0) { 
         prepareUpdateTableCell(); 
        } else if (tme.getColumn() == 1 && tme.getLastRow() == 1) { 
         executor.execute(new MyTask(MyTask.UPDATE_TABLE_COLUMN)); 
        } 
       } 
      } 
     }); 
     table.setRowHeight(30); 
     table.setFont(new Font("Serif", Font.BOLD, 20)); 
     table.getColumnModel().getColumn(0).setPreferredWidth(180); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     JScrollPane scrollPane = new JScrollPane(table); 
     add(scrollPane, BorderLayout.CENTER); 
     new Thread(this).start(); 
    } 

    private void prepareUpdateTableCell() { 
     timerRun = new javax.swing.Timer(10, UpdateTableCell()); 
     timerRun.setRepeats(false); 
     timerRun.start(); 
    } 

    private Action UpdateTableCell() { 
     return new AbstractAction("Update Table Cell") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       double dbl = ((Double) table.getModel().getValueAt(0, 1)) 
         - ((Integer) table.getModel().getValueAt(0, 2)); 
       table.getModel().setValueAt(dbl, 0, 3); 
      } 
     }; 
    } 

    @Override 
    public void run() { 
     while (runProcess) { 
      try { 
       Thread.sleep(250); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      changeTableValues(); 
     } 
    } 

    private void changeTableValues() { 
     Runnable doRun = new Runnable() { 

      @Override 
      public void run() { 
       table.getModel().setValueAt(random.nextInt(128) + random.nextDouble(), 0, 1); 
       table.getModel().setValueAt(random.nextInt(256) + random.nextDouble(), 1, 1); 
       table.getModel().setValueAt(random.nextInt(512) + random.nextDouble(), 2, 1); 

       table.getModel().setValueAt(random.nextInt(128), 0, 2); 
       table.getModel().setValueAt(random.nextInt(128), 1, 2); 
       table.getModel().setValueAt(random.nextInt(128), 2, 2); 
      } 
     }; 
     SwingUtilities.invokeLater(doRun); 
    } 

    private class MyTask extends SwingWorker<Void, Integer> { 

     private static final String UPDATE_TABLE_COLUMN = "update"; 
     private String namePr; 
     private double dbl; 

     MyTask(String str) { 
      this.namePr = str; 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      dbl = ((Double) table.getModel().getValueAt(1, 1)) 
        - ((Integer) table.getModel().getValueAt(1, 2)); 
      return null; 
     } 

     @Override 
     protected void done() { 
      SwingUtilities.invokeLater(new Runnable() { 

       @Override 
       public void run() { 
        table.getModel().setValueAt(dbl, 1, 3); 
       } 
      }); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ChangeNotifiersOnEvent frame = new ChangeNotifiersOnEvent(); 
       frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
       frame.setLocation(150, 150); 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
+0

आपका MyTask.done() कार्यान्वयन क्यों invokeLater का उपयोग करता है? यदि आपको ईडीटी पर कुछ करने की ज़रूरत है() आपका मौका है। – Ryan

+0

@Ryan कोड परीक्षण उद्देश्यों के लिए है, invokeLater ---> ए) ईडीटी को सूचित करें, बी) ईडीटी के अंत में वांछित कोड को स्थानांतरित करना (कई बार JTextComponents और इसके XxxListeners, फोकस इत्यादि के लिए उल्लिखित ...), निश्चित कार्यान्वयन एपीआई में किए गए, प्रक्रिया, प्रकाशित, सेटप्रोसेस की गारंटी है कि सभी घटनाएं ईडीटी पर की जाती हैं, श्रीमान मैं नफरत कर रहा हूं स्विंगवॉकर – mKorbel

+0

एक स्विंगवॉर्कर डोन() विधि जो केवल एक invokeLater विरोधी पैटर्न की तरह गंध करता है। मैं समझता हूं "बी/सी परीक्षण"। मुझे अभी भी विश्वास नहीं है) या बी) इस उदाहरण में कुछ भी हासिल करें। यदि आप कुछ समझने की कोशिश कर रहे हैं जिसमें अनावश्यक थ्रेडिंग क्विर्क मदद नहीं करते हैं। – Ryan

उत्तर

5

मुझे लगता है उसका मतलब है कि यदि आप वास्तव में अपने कोड के बारे में नहीं सोचते हैं तो आप एक अनंत लूप पेश कर सकते हैं।

अधिकांश लोग जब टेबल बनाते हैं तो संभवतः कॉलम 1, 2 संपादन योग्य बनाते हैं और कॉलम 3 को कॉलम 3 बनाते हैं क्योंकि केवल दो स्तंभों के बीच अंतर होता है।

इसलिए जब वे TableModelListener वे अद्यतन ईवेंट की जांच, लेकिन भूल जाते हैं को देखने के लिए जो स्तंभ अद्यतन किया जाता है क्योंकि उन्हें लगता है तालिका उन्हें स्तंभ अद्यतन करने के लिए 3.

वे पाते हैं कि जब भूल जाते हैं अनुमति नहीं दी जाएगी जाँच करने के बारे में TableModelListener कॉलम 3 अपडेट करता है एक और अद्यतन घटना उत्पन्न होगी जिससे इस प्रकार अनंत लूप हो जाएगा। बेशक, आपके कोड में उचित कोडिंग, लूप को रोक देगा।

सामान्यतः, इसे अपवाद नहीं होना चाहिए।

दूसरा बिंदु व्यापार नियमों के बारे में है। व्यवसाय के नियमों को एक ही स्थान पर परिभाषित किया जाना चाहिए, इस मामले में मॉडल। डेटा स्वयं और डेटा को अपडेट करना एक ही स्थान पर किया जाना चाहिए।

+1

स्पष्टीकरण के लिए धन्यवाद, +1 – mKorbel

संबंधित मुद्दे