दिलचस्प पोस्ट
लोड किए गए पासा के लिए डेटा संरचना? मैं 2 डी अंक को 3 डी में कैसे बदल सकता हूं? आप C ++ में निर्भर नाम कैसे समझते हैं जावास्क्रिप्ट: गतिशील रूप से नेस्टेड ऑब्जेक्ट्स को एक ऑरेंज द्वारा दिए गए ऑब्जेक्ट नामों का उपयोग करने के लिए कैसे करें पुस्तकालयों के साथ मेकफाइल बनाना SQL सर्वर से डेटाबेस की सूची प्राप्त करें कितनी तारीखों के साथ तालिका को आबाद करना है? जीआईटी: मैं फॉक्ट्रॉट को अपने 'मास्टर' शाखा में कैसे विलीन कर सकता हूं? कैसे टॉमकेट एम्बेड 6? एक UILabel / UITextView में छुआ शब्द प्राप्त करना HTML चपलता पैक – सामग्री को निकाले बिना अवांछित टैग को निकाल रहा है? एनजी-दोहराने के उपयोग की सूची पर अंक लगाना स्काला में किस प्रकार की कक्षाएं उपयोगी हैं? MySQL: ग्रुप बाय में नहीं है रूबी ऑपरेटरों की सूची जिसे ओवरराइड / कार्यान्वित किया जा सकता है

जेएस बंडलर OSXAdapter का उपयोग करने के कारण अंतराल या समाप्त करने के लिए आवेदन करता है

मैंने एक साधारण जावा एप्लिकेशन बनाया है जो कि प्रत्येक सेकेंड 10 सेकंड के लिए लगातार सेकंड जेटीलेबल में एक नई पंक्ति जोड़ता है। इसमें तीन वर्ग हैं।

एक बार कार्यक्रम शुरू होने पर मुख्य वर्ग को शुरू किया जाता है

 public class JarBundlerProblem { public static void main(String[] args) { System.err.println("Initializing controller"); new Controller(); } } 

एक नियंत्रक जो जीयूआई बनाता है और इसे doWork() माध्यम से बदल देता है doWork()

 public class Controller { public Controller() { doWork(null); } public static void doWork(String s) { GUI gui = new GUI(); for (int i=0; i<10; i++) { gui.addRow("Line "+(i+1)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } 

और अंत में, जीयूआई

 import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class GUI { private JFrame frame = new JFrame(); private DefaultTableModel model = new DefaultTableModel(); private JTable table = new JTable(model); private JScrollPane pane = new JScrollPane(table); public GUI() { model.addColumn("Name"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(pane); frame.pack(); frame.setVisible(true); } public void addRow(String name) { model.addRow(new Object[]{name}); } } 

चूंकि मैं ओएस एक्स के लिए विकास कर रहा हूं, और मुझे अपने आवेदन को एक निश्चित फ़ाइल प्रकार के साथ संबद्ध करने की आवश्यकता है (चलो कहना है। .jarbundlerproblem ), मुझे अपने JAR फ़ाइल को ऐप्पल जार बंडलर के उपयोग से APP में बंडल करना होगा। मैंने यह सफलतापूर्वक किया है, मेरा आवेदन खुलता है, दस की गणना करता है, प्रत्येक सेकेंड को लिखना

अब, समस्या के लिए

डिफ़ॉल्ट रूप से, .jarbundlerproblem पर डबल-क्लिक .jarbundlerproblem , और फ़ाइल को मेरे अनुप्रयोग से .jarbundlerproblem , वह फाइल नहीं देगा जो मैं अनुप्रयोग के लिए एक तर्क के रूप में डबल-क्लिक किया। जाहिर है, यह सिर्फ ओएस एक्स काम करता है पर जावा है

चूंकि मुझे यह देखने में सक्षम होना चाहिए कि किस फ़ाइल को डबल-क्लिक किया गया था, मैं OSXAdapter का उपयोग कर रहा हूं जो कि उद्देश्य के लिए एप्पल द्वारा बनाई गई जावा लाइब्रेरी है। यह, मैंने अपने Controller वर्ग के कन्स्ट्रक्टर को बदलकर कार्यान्वित किया है और एक और विधि registerForMacOSXEvents() जोड़ा है:

 public Controller() { registerForMacOSXEvents(); //doWork(null); } public void registerForMacOSXEvents() { try { OSXAdapter.setFileHandler(this, getClass().getDeclaredMethod("doWork", new Class[] { String.class })); } catch (Exception e) { System.err.println("Error while loading the OSXAdapter:"); e.printStackTrace(); } } 

लेकिन इस (मामूली) संशोधन के बाद, मेरा आवेदन शुरू करना शुरू होता है। कभी-कभी, यह खुला नहीं है, भले ही मैं कंसोल में देख सकता हूं कि यह अभी शुरू हुआ ( Initializing controller शुरू Initializing controller है), लेकिन कुछ प्रयासों के बाद, यह अंततः शुरू हो जाएगा, लेकिन खिड़कियां पहले 10 सेकेंड , और उसके बाद, 10 पंक्तियाँ जोड़ दी जाएंगी।

मदद

अब, मैं इस काफी कुछ के साथ संघर्ष किया है, और ऐसा लगता है कि न तो OSX एडाप्टर और न ही जार बंडलर के बारे में बहुत सारे दस्तावेज़ हैं मैं क्या गलत कर रहा हूं? या मैं पहली जगह में OSXAdapter या जार बंडलर का उपयोग नहीं करना चाहिए?

Solutions Collecting From Web of "जेएस बंडलर OSXAdapter का उपयोग करने के कारण अंतराल या समाप्त करने के लिए आवेदन करता है"

ऐसा करने के बाद, मुझे पूरी तरह से आश्वस्त नहीं है कि स्विंगवॉर्कर एक सरल (उर्फ: बेहतर) समाधान है – फिर भी अतिरिक्त थ्रेड सिंकिंग (कार्यकर्ता थ्रेड और "बाहरी" धागा जो फ़ाइल / नाम से गुजरता है) के बीच है। वैसे भी (सीखने का मौका लेना, और त्रुटियों से होकर :), नीचे मूल विचार के लिए अवधारणा उदाहरण का एक कच्चा प्रमाण है:

  • नियंत्रक को स्विंगवर्कर के रूप में लागू करें, जो बाहरी थ्रेड से इनपुट को EDT में फ़नल करता है
  • इसे एक विधि doWork (..) के माध्यम से इनपुट (एडेप्टर, फाई से) स्वीकार करता है जो प्रकाशित करने के लिए इनपुट की कतार
  • इनपुट को सफलतापूर्वक प्रकाशित करने के लिए doInBackground को लागू करें

खुले मामले

  • स्थानीय सूची तक पहुँच (एकसमय में एक विशेषज्ञ नहीं, लेकिन बहुत यकीन है कि करने की जरूरत है)
  • मज़बूती से बाह्य धागा के अंत का पता लगा रहा है (इनपुट कतार रिक्त होने पर बस इसे रोकता है)

प्रतिक्रिया स्वागत है 🙂

 public class GUI { private JFrame frame = new JFrame(); private DefaultTableModel model = new DefaultTableModel(); private JTable table = new JTable(model); private JScrollPane pane = new JScrollPane(table); public GUI() { model.addColumn("Name"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(pane); frame.pack(); frame.setVisible(true); } public void addRow(String name) { model.addRow(new Object[] { name }); } /** * Controller is a SwingWorker. */ public static class Controller extends SwingWorker<Void, String> { private GUI gui; private List<String> pending; public Controller() { gui = new GUI(); } public void doWork(String newLine) { if (pending == null) { pending = new ArrayList<String>(); pending.add(newLine); execute(); } else { pending.add(newLine); } } @Override protected Void doInBackground() throws Exception { while (pending.size() > 0) { publish(pending.remove(0)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } /** * @inherited <p> */ @Override protected void process(List<String> chunks) { for (String object : chunks) { gui.addRow(object); } } } /** * Simulating the adapter. * * Obviously, the real-thingy wouldn't have a reference * to the controller, but message the doWork refectively */ public static class Adapter implements Runnable { Controller controller; public Adapter(Controller controller) { this.controller = controller; } @Override public void run() { for (int i=0; i<10; i++) { controller.doWork("Line "+(i+1)); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { System.err.println("Initializing controller"); new Adapter(new Controller()).run(); } @SuppressWarnings("unused") private static final Logger LOG = Logger.getLogger(GUI.class.getName()); } 

ऐसा लगता है कि आप ईवेंट प्रेषण थ्रेड (एडीटी) को अवरुद्ध कर रहे हैं। SwingWorker एक बेहतर विकल्प होगा, लेकिन यह उदाहरण SwingWorker को लागू करता है।

परिशिष्ट: आप MVC आर्किटेक्चर के उदाहरण के लिए इस प्रोजेक्ट को देख सकते हैं। यह यह भी दिखाता है कि जेएआर बंडलर का उपयोग किए बिना मैक ओएस एप्लीकेशन बंडल का निर्माण कैसे करें एमवीसी पर अधिक जानकारी यहां मिल सकती है।

एक तरफ, यह उदाहरण एक JTable ऑटो-स्क्रॉल करने के लिए एक दृष्टिकोण दिखाता है स्क्रॉल को निलंबित करने के लिए अंगूठे पर क्लिक करें; फिर से शुरू करने के लिए जारी

परिशिष्ट: आपका एप्लिकेशन स्टार्टअप पर 10 सेकंड के लिए लंबा है। चूंकि यह सटीक समय है जिसके लिए Controller सोता है, यह निश्चित रूप से ईडीटी पर सो रहा है। एक एसएससीसीए डिस्पोजेबल होगा इसके बजाय, दूसरे थ्रेड पर काम करें और EDT पर मॉडल को अपडेट करें। SwingWorker में एक process() विधि होती है जो स्वचालित रूप से करती है, या आप नीचे दिखाए गए अनुसार invokeLater() उपयोग कर सकते हैं। जब तक आपका आवेदन सही ढंग से सिंक्रनाइज़ नहीं हो जाता है, तब तक एप्पल की घटनाओं को काम करने की कोई उम्मीद नहीं है।

परिशिष्ट: आप isDispatchThread() को Controller में चेक कर सकते हैं। उद्धृत परियोजना में मैक एप्लिकेशन के साथ। dist2 और एक ant फ़ाइल शामिल है जो लक्षित dist2 जरिए बंडल बना dist2

परिशिष्ट: यहाँ दिखाए गए वैकल्पिक तरीकों को भी देखें

यहां छवि विवरण दर्ज करें

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; /** @seehttps://stackoverflow.com/questions/7519244 */ public class TableAddTest extends JPanel implements Runnable { private static final int N_ROWS = 8; private static String[] header = {"ID", "String", "Number", "Boolean"}; private DefaultTableModel dtm = new DefaultTableModel(null, header) { @Override public Class<?> getColumnClass(int col) { return getValueAt(0, col).getClass(); } }; private JTable table = new JTable(dtm); private JScrollPane scrollPane = new JScrollPane(table); private JScrollBar vScroll = scrollPane.getVerticalScrollBar(); private JProgressBar jpb = new JProgressBar(); private int row; private boolean isAutoScroll; public TableAddTest() { this.setLayout(new BorderLayout()); jpb.setIndeterminate(true); this.add(jpb, BorderLayout.NORTH); Dimension d = new Dimension(320, N_ROWS * table.getRowHeight()); table.setPreferredScrollableViewportSize(d); for (int i = 0; i < N_ROWS; i++) { addRow(); } scrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); vScroll.addAdjustmentListener(new AdjustmentListener() { @Override public void adjustmentValueChanged(AdjustmentEvent e) { isAutoScroll = !e.getValueIsAdjusting(); } }); this.add(scrollPane, BorderLayout.CENTER); JPanel panel = new JPanel(); panel.add(new JButton(new AbstractAction("Add Row") { @Override public void actionPerformed(ActionEvent e) { addRow(); } })); this.add(panel, BorderLayout.SOUTH); } private void addRow() { char c = (char) ('A' + row++ % 26); dtm.addRow(new Object[]{ Character.valueOf(c), String.valueOf(c) + String.valueOf(row), Integer.valueOf(row), Boolean.valueOf(row % 2 == 0) }); } private void scrollToLast() { if (isAutoScroll) { int last = table.getModel().getRowCount() - 1; Rectangle r = table.getCellRect(last, 0, true); table.scrollRectToVisible(r); } } @Override public void run() { while (true) { EventQueue.invokeLater(new Runnable() { @Override public void run() { addRow(); } }); EventQueue.invokeLater(new Runnable() { @Override public void run() { scrollToLast(); } }); try { Thread.sleep(1000); // simulate latency } catch (InterruptedException ex) { System.err.println(ex); } } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); TableAddTest nlt = new TableAddTest(); f.add(nlt); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); new Thread(nlt).start(); } }); } } 

यहां @ क्लीओपेट्रा के उदाहरण की एक विविधता है जिसमें एक सतत चलने वाला Controller doWork() में नई प्रविष्टियां स्वीकार करता है, जबकि एक SwingWorker pending प्रविष्टियों को अपनी पृष्ठभूमि थ्रेड में SwingWorker संसाधित करता है। ArrayBlockingQueue सिंक्रनाइज़ेशन को संभालता है

 import java.awt.EventQueue; import java.util.List; import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingWorker; import javax.swing.table.DefaultTableModel; public class GUI { private static final Random rnd = new Random(); private JFrame frame = new JFrame(); private DefaultTableModel model = new DefaultTableModel(); private JTable table = new JTable(model); private JScrollPane pane = new JScrollPane(table); public GUI() { model.addColumn("Name"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(pane); frame.pack(); frame.setVisible(true); } public void addRow(String name) { model.addRow(new Object[]{name}); } /** * Controller is a SwingWorker. */ private static class Controller extends SwingWorker<Void, String> { private static final int MAX = 5; private GUI gui; private BlockingQueue<String> pending = new ArrayBlockingQueue<String>(MAX); public Controller() { EventQueue.invokeLater(new Runnable() { @Override public void run() { gui = new GUI(); } }); } private void doWork(String newLine) { try { pending.put(newLine); } catch (InterruptedException e) { e.printStackTrace(System.err); } } @Override protected Void doInBackground() throws Exception { while (true) { // may block if nothing pending publish(pending.take()); try { Thread.sleep(rnd.nextInt(500)); // simulate latency } catch (InterruptedException e) { e.printStackTrace(System.err); } } } @Override protected void process(List<String> chunks) { for (String object : chunks) { gui.addRow(object); } } } /** * Exercise the Controller. */ private static class Adapter implements Runnable { private Controller controller; private Adapter(Controller controller) { this.controller = controller; } @Override public void run() { controller.execute(); int i = 0; while (true) { // may block if Controller busy controller.doWork("Line " + (++i)); try { Thread.sleep(rnd.nextInt(500)); // simulate latency } catch (InterruptedException e) { e.printStackTrace(System.err); } } } } public static void main(String[] args) { System.out.println("Initializing controller"); // Could run on inital thread via // new Adapter(new Controller()).run(); // but we'll start a new one new Thread(new Adapter(new Controller())).start(); } }