();
391 | for (ZVNode node : children.get(parent)) {
392 | if (node.exists()) {
393 | nodes.add(node);
394 | }
395 | }
396 | return nodes;
397 | }
398 |
399 | @Override
400 | public void addModelListener(ZVModelListener listener) {
401 | listenerList.add(ZVModelListener.class, listener);
402 | }
403 |
404 | @Override
405 | public void removeModelListener(ZVModelListener listener) {
406 | listenerList.remove(ZVModelListener.class, listener);
407 | }
408 |
409 | protected void fireNodeCreated(ZVNode newNode) {
410 | // Guaranteed to return a non-null array
411 | Object[] listeners = listenerList.getListenerList();
412 | // Process the listeners last to first, notifying
413 | // those that are interested in this event
414 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
415 | if (listeners[i] == ZVModelListener.class) {
416 | ((ZVModelListener) listeners[i + 1]).nodeCreated(newNode);
417 | }
418 | }
419 | }
420 |
421 | protected void fireNodeDeleted(ZVNode oldNode, int oldIndex) {
422 | // Guaranteed to return a non-null array
423 | Object[] listeners = listenerList.getListenerList();
424 | // Process the listeners last to first, notifying
425 | // those that are interested in this event
426 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
427 | if (listeners[i] == ZVModelListener.class) {
428 | ((ZVModelListener) listeners[i + 1]).nodeDeleted(oldNode,
429 | oldIndex);
430 | }
431 | }
432 | }
433 |
434 | protected void fireNodeDataChanged(ZVNode node) {
435 | // Guaranteed to return a non-null array
436 | Object[] listeners = listenerList.getListenerList();
437 | // Process the listeners last to first, notifying
438 | // those that are interested in this event
439 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
440 | if (listeners[i] == ZVModelListener.class) {
441 | ((ZVModelListener) listeners[i + 1]).nodeDataChanged(node);
442 | }
443 | }
444 | }
445 | }
446 |
--------------------------------------------------------------------------------
/src/main/java/net/isammoc/zooviewer/model/ZVModelListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This program is free software: you can redistribute it and/or modify
3 | * it under the terms of the GNU Lesser General Public License as published by
4 | * the Free Software Foundation, either version 3 of the License, or
5 | * (at your option) any later version.
6 | *
7 | * This program is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | * GNU Lesser General Public License for more details.
11 | *
12 | * You should have received a copy of the GNU Lesser General Public License
13 | * along with this program. If not, see .
14 | */
15 | package net.isammoc.zooviewer.model;
16 |
17 | import java.util.EventListener;
18 |
19 | import net.isammoc.zooviewer.node.ZVNode;
20 |
21 | public interface ZVModelListener extends EventListener {
22 | void nodeCreated(ZVNode newNode);
23 |
24 | void nodeDeleted(ZVNode oldNode, int oldIndex);
25 |
26 | void nodeDataChanged(ZVNode node);
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/net/isammoc/zooviewer/node/JZVNode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This program is free software: you can redistribute it and/or modify
3 | * it under the terms of the GNU Lesser General Public License as published by
4 | * the Free Software Foundation, either version 3 of the License, or
5 | * (at your option) any later version.
6 | *
7 | * This program is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | * GNU Lesser General Public License for more details.
11 | *
12 | * You should have received a copy of the GNU Lesser General Public License
13 | * along with this program. If not, see .
14 | */
15 | package net.isammoc.zooviewer.node;
16 |
17 | import java.awt.BorderLayout;
18 | import java.awt.Dimension;
19 | import java.awt.GridBagConstraints;
20 | import java.awt.GridBagLayout;
21 | import java.awt.Insets;
22 | import java.awt.event.ActionEvent;
23 | import java.awt.event.KeyEvent;
24 | import java.beans.PropertyChangeEvent;
25 | import java.beans.PropertyChangeListener;
26 | import java.util.ResourceBundle;
27 |
28 | import javax.swing.AbstractAction;
29 | import javax.swing.Action;
30 | import javax.swing.BorderFactory;
31 | import javax.swing.JButton;
32 | import javax.swing.JLabel;
33 | import javax.swing.JOptionPane;
34 | import javax.swing.JPanel;
35 | import javax.swing.JTextArea;
36 | import javax.swing.JTextField;
37 | import javax.swing.KeyStroke;
38 | import javax.swing.border.BevelBorder;
39 | import javax.swing.border.Border;
40 | import javax.swing.border.TitledBorder;
41 | import javax.swing.event.DocumentEvent;
42 | import javax.swing.event.DocumentListener;
43 | import javax.swing.text.BadLocationException;
44 |
45 | import net.isammoc.zooviewer.model.ZVModel;
46 | import net.isammoc.zooviewer.model.ZVModelListener;
47 |
48 | /**
49 | * Editor panel for a node.
50 | *
51 | * @author franck
52 | */
53 | public class JZVNode extends JPanel {
54 | private static final Border BEVEL_LOWERED_BORDER = BorderFactory
55 | .createBevelBorder(BevelBorder.LOWERED);
56 |
57 | private static final String ADD_CHILD_NODE_KEY = "btn.add.child";
58 | private static final String UPDATE_NODE_KEY = "btn.update";
59 | private static final String DELETE_NODE_KEY = "btn.delete";
60 |
61 | /** */
62 | private static final long serialVersionUID = 1L;
63 |
64 | private static final ResourceBundle bundle = ResourceBundle
65 | .getBundle(JZVNode.class.getCanonicalName());
66 |
67 | private final TitledBorder titleBorder = BorderFactory
68 | .createTitledBorder("-");
69 |
70 | private ZVNode[] nodes;
71 | private final ZVModel model;
72 |
73 | private final JButton jbNewChild = new JButton();
74 | private final JButton jbUpdate = new JButton();
75 | private final JButton jbDelete = new JButton();
76 |
77 | private final JTextArea taChildData = new JTextArea();
78 | private final JTextField jtfChildName = new JTextField();
79 | private final JZVStat jzvStat = new JZVStat();
80 | private final JTextArea taUpdate = new JTextArea();
81 |
82 | private Action addChildAction = null;
83 | private Action updateAction = null;
84 | private Action deleteAction = null;
85 |
86 | private JPanel nodePanel = null;
87 | private JPanel deletePanel = null;
88 | private JPanel statsPanel = null;
89 | private JPanel dataPanel = null;
90 | private JPanel newChildPanel = null;
91 |
92 | private final PropertyChangeListener propertyListener = new PropertyChangeListener() {
93 | @Override
94 | public void propertyChange(PropertyChangeEvent evt) {
95 | updateView();
96 | }
97 | };
98 |
99 | /**
100 | * Constructs a new editor panel.
101 | *
102 | * @param model
103 | * the model
104 | */
105 | public JZVNode(ZVModel model) {
106 | super(new BorderLayout());
107 |
108 | this.model = model;
109 | this.model.addModelListener(new RefreshZVModelListener());
110 |
111 | // Components
112 | this.taChildData.setBorder(BEVEL_LOWERED_BORDER);
113 | this.taUpdate.setBorder(BEVEL_LOWERED_BORDER);
114 | this.taUpdate.setRows(2);
115 | this.taChildData.setRows(2);
116 |
117 | // Actions
118 | this.jbDelete.setAction(getDeleteAction());
119 | this.jbNewChild.setAction(getAddChildAction());
120 | this.jbUpdate.setAction(getUpdateAction());
121 |
122 | // Main content
123 | this.add(getNodePanel());
124 | this.updateView();
125 |
126 | Dimension prefSize = this.jbNewChild.getPreferredSize();
127 | this.jbDelete.setPreferredSize( prefSize );
128 | this.jbNewChild.setPreferredSize( prefSize );
129 | this.jbUpdate.setPreferredSize( prefSize );
130 |
131 | initListeners();
132 | }
133 |
134 | /**
135 | * Returns the main node panel.
136 | *
137 | * @return the panel
138 | */
139 | private JPanel getNodePanel() {
140 | if (nodePanel == null) {
141 | nodePanel = new JPanel(new GridBagLayout());
142 |
143 | // Sub-panels
144 | int row = 0;
145 | nodePanel.add(
146 | getDeletePanel(),
147 | new GridBagConstraints(0, row, 1, 1, 1, 1,
148 | GridBagConstraints.WEST, GridBagConstraints.BOTH,
149 | new Insets(2, 2, 2, 2), 0, 0));
150 | nodePanel.add(
151 | getStatsPanel(),
152 | new GridBagConstraints(1, row++, 4, 1, 1, 1,
153 | GridBagConstraints.WEST, GridBagConstraints.BOTH,
154 | new Insets(2, 2, 2, 2), 0, 0));
155 |
156 | nodePanel.add(
157 | getDataPanel(),
158 | new GridBagConstraints(0, row++, 5, 1, 1, 1,
159 | GridBagConstraints.WEST, GridBagConstraints.BOTH,
160 | new Insets(2, 2, 2, 2), 0, 0));
161 |
162 | nodePanel.add(
163 | getNewChildPanel(),
164 | new GridBagConstraints(0, row++, 5, 1, 1, 1,
165 | GridBagConstraints.WEST, GridBagConstraints.BOTH,
166 | new Insets(2, 2, 2, 2), 0, 0));
167 | }
168 | return nodePanel;
169 | }
170 |
171 | private JPanel getDeletePanel() {
172 | if (deletePanel == null) {
173 | deletePanel = new JPanel(new GridBagLayout());
174 | deletePanel.setBorder(this.titleBorder);
175 | deletePanel.add(this.jbDelete, new GridBagConstraints(0, 0, 1, 1,
176 | 1, 1, GridBagConstraints.SOUTHWEST,
177 | GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
178 | }
179 | return deletePanel;
180 | }
181 |
182 | /**
183 | * Returns the panel displaying the node stats.
184 | *
185 | * @return the panel
186 | */
187 | private JPanel getStatsPanel() {
188 | if (statsPanel == null) {
189 | statsPanel = new JPanel(new BorderLayout());
190 | statsPanel.setBorder(BorderFactory.createTitledBorder(bundle
191 | .getString("pnl.stat")));
192 | statsPanel.add(this.jzvStat);
193 | }
194 | return statsPanel;
195 | }
196 |
197 | private JPanel getDataPanel() {
198 | if (dataPanel == null) {
199 | dataPanel = new JPanel(new GridBagLayout());
200 | dataPanel.setBorder(BorderFactory.createTitledBorder(bundle
201 | .getString("pnl.data")));
202 | dataPanel.add(this.jbUpdate, new GridBagConstraints(0, 0, 1, 1,
203 | 0, 0, GridBagConstraints.SOUTHWEST,
204 | GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
205 | dataPanel.add(this.taUpdate, new GridBagConstraints(1, 0, 1, 1,
206 | 1, .5, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
207 | new Insets(2, 2, 2, 2), 0, 0));
208 | }
209 | return dataPanel;
210 | }
211 |
212 | private JPanel getNewChildPanel() {
213 | if (newChildPanel == null) {
214 | newChildPanel = new JPanel(new GridBagLayout());
215 | newChildPanel.setBorder(BorderFactory.createTitledBorder(bundle
216 | .getString("pnl.new.child")));
217 | newChildPanel.add(
218 | new JLabel(bundle.getString("pnl.new.child.lbl.name")),
219 | new GridBagConstraints(0, 0, 1, 1, 0, 0,
220 | GridBagConstraints.WEST,
221 | GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2,
222 | 2), 0, 0));
223 | newChildPanel.add(this.jtfChildName,
224 | new GridBagConstraints(1, 0, 1, 1, 1, .2,
225 | GridBagConstraints.NORTHWEST,
226 | GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2,
227 | 2), 0, 0));
228 | newChildPanel.add(
229 | new JLabel(bundle.getString("pnl.new.child.lbl.data")),
230 | new GridBagConstraints(0, 1, 1, 1, 0, 0,
231 | GridBagConstraints.NORTHWEST,
232 | GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2,
233 | 2), 0, 0));
234 | newChildPanel.add(this.taChildData, new GridBagConstraints(1, 1, 1,
235 | 2, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH,
236 | new Insets(2, 2, 2, 2), 0, 0));
237 |
238 | newChildPanel.add(this.jbNewChild, new GridBagConstraints(0, 1, 1,
239 | 2, 0, 0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE,
240 | new Insets(2, 2, 2, 2), 0, 0));
241 | }
242 | return newChildPanel;
243 | }
244 |
245 | /**
246 | * Returns the 'Add child' action.
247 | *
248 | * @return the action
249 | */
250 | @SuppressWarnings("serial")
251 | private Action getAddChildAction() {
252 | if (addChildAction == null) {
253 | String actionCommand = bundle.getString(ADD_CHILD_NODE_KEY);
254 | String actionKey = bundle.getString(ADD_CHILD_NODE_KEY + ".action");
255 | addChildAction = new AbstractAction(actionCommand) {
256 | @Override
257 | public void actionPerformed(ActionEvent e) {
258 | System.out.println("actionPerformed(): action = "
259 | + e.getActionCommand());
260 | if (checkAction()) {
261 | model.addNode(
262 | nodes[0].getPath() + "/"
263 | + jtfChildName.getText(), taChildData
264 | .getText().getBytes());
265 | }
266 | }
267 |
268 | private boolean checkAction() {
269 | // No node or several nodes selected
270 | if (nodes == null || nodes.length > 1) {
271 | return false;
272 | }
273 | // Emptry node name
274 | if (jtfChildName.getText().isEmpty()) {
275 | JOptionPane.showMessageDialog(JZVNode.this,
276 | bundle.getString("dlg.error.addWithoutName"),
277 | bundle.getString("dlg.error.title"),
278 | JOptionPane.ERROR_MESSAGE);
279 | return false;
280 | }
281 | // No parent
282 | if (nodes == null || nodes.length != 1) {
283 | JOptionPane.showMessageDialog(JZVNode.this,
284 | bundle.getString("dlg.error.addWithoutParent"),
285 | bundle.getString("dlg.error.title"),
286 | JOptionPane.ERROR_MESSAGE);
287 | return false;
288 | }
289 | return true;
290 | }
291 | };
292 | addChildAction.putValue(Action.ACTION_COMMAND_KEY, actionKey);
293 | }
294 | return this.addChildAction;
295 | }
296 |
297 | /**
298 | * Returns the 'Update' action.
299 | *
300 | * @return the action
301 | */
302 | @SuppressWarnings("serial")
303 | private Action getUpdateAction() {
304 | if (updateAction == null) {
305 | String actionCommand = bundle.getString(UPDATE_NODE_KEY);
306 | String actionKey = bundle.getString(UPDATE_NODE_KEY + ".action");
307 | updateAction = new AbstractAction(actionCommand) {
308 | @Override
309 | public void actionPerformed(ActionEvent e) {
310 | System.out.println("actionPerformed(): action = "
311 | + e.getActionCommand());
312 | if (checkAction()) {
313 | model.updateData(nodes[0].getPath(), taUpdate
314 | .getText().getBytes());
315 | }
316 | }
317 |
318 | private boolean checkAction() {
319 | // No node or several nodes selected
320 | if (nodes == null || nodes.length > 1) {
321 | return false;
322 | }
323 | // No parent
324 | if (nodes == null || nodes.length != 1) {
325 | JOptionPane.showMessageDialog(JZVNode.this, bundle
326 | .getString("dlg.error.updateWithoutParent"),
327 | bundle.getString("dlg.error.title"),
328 | JOptionPane.ERROR_MESSAGE);
329 | return false;
330 | }
331 | return true;
332 | }
333 | };
334 | updateAction.putValue(Action.ACTION_COMMAND_KEY, actionKey);
335 | }
336 | return updateAction;
337 | }
338 |
339 | /**
340 | * Returns the 'Delete node(s)' action.
341 | *
342 | * The action is created and mapped to the [Delete] key stroke
343 | *
344 | *
345 | * @return the action
346 | */
347 | @SuppressWarnings("serial")
348 | private Action getDeleteAction() {
349 | if (this.deleteAction == null) {
350 | String actionCommand = bundle.getString(DELETE_NODE_KEY);
351 | String actionKey = bundle.getString(DELETE_NODE_KEY + ".action");
352 | this.deleteAction = new AbstractAction(actionCommand) {
353 | @Override
354 | public void actionPerformed(ActionEvent e) {
355 | System.out.println("actionPerformed(): action = "
356 | + e.getActionCommand());
357 | if (checkAction()) {
358 | // Checks if several nodes will be deleted
359 | if (nodes.length > 1) {
360 | model.deleteNodes(nodes);
361 | } else {
362 | model.deleteNode(nodes[0]);
363 | }
364 | }
365 | }
366 |
367 | private boolean checkAction() {
368 | // No node selected
369 | if (nodes == null) {
370 | JOptionPane.showMessageDialog(JZVNode.this, bundle
371 | .getString("dlg.error.deleteWithoutSelection"),
372 | bundle.getString("dlg.error.title"),
373 | JOptionPane.ERROR_MESSAGE);
374 | return false;
375 | }
376 | return true;
377 | }
378 | };
379 | this.deleteAction.putValue(Action.ACTION_COMMAND_KEY, actionKey);
380 |
381 | this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(
382 | KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), actionKey);
383 | this.getActionMap().put(actionKey, this.deleteAction);
384 | }
385 | return this.deleteAction;
386 | }
387 |
388 | /**
389 | * Defines the list of selected nodes.
390 | *
391 | * @param nodes
392 | * the selected nodes
393 | */
394 | public void setNodes(ZVNode[] nodes) {
395 | if (this.nodes != null) {
396 | for (int i = 0; i < this.nodes.length; i++) {
397 | this.nodes[i].removePropertyChangeListener(
398 | ZVNode.PROPERTY_EXISTS, this.propertyListener);
399 | }
400 | }
401 | this.nodes = nodes;
402 | if (this.nodes != null) {
403 | for (int i = 0; i < this.nodes.length; i++) {
404 | this.nodes[i].addPropertyChangeListener(ZVNode.PROPERTY_EXISTS,
405 | this.propertyListener);
406 | }
407 | }
408 | this.updateView();
409 | }
410 |
411 | private void initListeners() {
412 | taUpdate.getDocument().addDocumentListener( new DocumentListener() {
413 | @Override
414 | public void removeUpdate(DocumentEvent e) {
415 | enableAction(e);
416 | }
417 | @Override
418 | public void insertUpdate(DocumentEvent e) {
419 | enableAction(e);
420 | }
421 | @Override
422 | public void changedUpdate(DocumentEvent e) {
423 | enableAction(e);
424 | }
425 | private void enableAction(DocumentEvent e) {
426 | boolean enabled = e.getDocument().getLength() > 0;
427 | getUpdateAction().setEnabled( enabled );
428 | }
429 | });
430 | jtfChildName.getDocument().addDocumentListener( new DocumentListener() {
431 | @Override
432 | public void removeUpdate(DocumentEvent e) {
433 | System.out.println(".removeUpdate()");
434 | enableAction(e);
435 | }
436 | @Override
437 | public void insertUpdate(DocumentEvent e) {
438 | System.out.println(".insertUpdate()");
439 | enableAction(e);
440 | }
441 | @Override
442 | public void changedUpdate(DocumentEvent e) {
443 | System.out.println(".changedUpdate()");
444 | enableAction(e);
445 | }
446 | private void enableAction(DocumentEvent e) {
447 | int docLength = e.getDocument().getLength();
448 | boolean enabled;
449 | try {
450 | enabled = ( docLength > 0 )
451 | && !e.getDocument().getText(0, docLength).trim().equals("");
452 | getAddChildAction().setEnabled( enabled );
453 | } catch (BadLocationException e1) {
454 | // TODO Auto-generated catch block
455 | e1.printStackTrace();
456 | }
457 | }
458 | });
459 | }
460 |
461 | /**
462 | * Updates the view.
463 | *
464 | * If a node is selected, its data & stats are displayed. If no node is
465 | * selected (or several nodes are selected), the view is cleared.
466 | *
467 | */
468 | private void updateView() {
469 | if (this.nodes == null || this.nodes.length > 1
470 | || !this.nodes[0].exists()) {
471 | this.titleBorder.setTitle("-");
472 | this.jzvStat.setStat(null);
473 | this.taUpdate.setText("");
474 | this.taChildData.setText("");
475 | this.jbUpdate.setEnabled(false);
476 | this.jbNewChild.setEnabled(false);
477 | this.jbDelete.setEnabled(this.nodes != null);
478 | } else {
479 | this.titleBorder.setTitle(this.nodes[0].getPath());
480 | this.jzvStat.setStat(this.nodes[0].getStat());
481 | byte[] data = this.nodes[0].getData();
482 | this.taUpdate.setText(new String(data == null ? "null".getBytes()
483 | : data));
484 | this.taChildData.setText("");
485 | this.jbUpdate.setEnabled( !this.taUpdate.getText().trim().equals("") );
486 | this.jbNewChild.setEnabled( !this.jtfChildName.getText().trim().equals("") );
487 | this.jbDelete.setEnabled(true);
488 | }
489 | this.repaint();
490 | }
491 |
492 | /**
493 | * Class managing events in order to update the view.
494 | */
495 | private final class RefreshZVModelListener implements ZVModelListener {
496 | @Override
497 | public void nodeDeleted(ZVNode oldNode, int oldIndex) {
498 | if (nodes != null) {
499 | for (int i = 0; i < nodes.length; i++) {
500 | if ((nodes[i] == oldNode)
501 | || (nodes[i] == model.getParent(oldNode))) {
502 | updateView();
503 | break;
504 | }
505 | }
506 | }
507 | }
508 |
509 | @Override
510 | public void nodeDataChanged(ZVNode node) {
511 | boolean updateView = false;
512 | if (nodes != null) {
513 | for (int i = 0; i < nodes.length; i++) {
514 | if ((nodes[i] == node)) {
515 | updateView = true;
516 | }
517 | }
518 | }
519 | if (updateView) {
520 | updateView();
521 | }
522 | }
523 |
524 | @Override
525 | public void nodeCreated(ZVNode newNode) {
526 | boolean updateView = false;
527 | if (nodes != null) {
528 | for (int i = 0; i < nodes.length; i++) {
529 | if ((nodes[i] == newNode)) {
530 | updateView = true;
531 | }
532 | }
533 | }
534 | if (updateView) {
535 | updateView();
536 | }
537 | }
538 | }
539 | }
--------------------------------------------------------------------------------
/src/main/java/net/isammoc/zooviewer/node/JZVStat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This program is free software: you can redistribute it and/or modify
3 | * it under the terms of the GNU Lesser General Public License as published by
4 | * the Free Software Foundation, either version 3 of the License, or
5 | * (at your option) any later version.
6 | *
7 | * This program is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | * GNU Lesser General Public License for more details.
11 | *
12 | * You should have received a copy of the GNU Lesser General Public License
13 | * along with this program. If not, see .
14 | */
15 | package net.isammoc.zooviewer.node;
16 |
17 | import java.awt.BorderLayout;
18 | import java.awt.GridLayout;
19 | import java.text.DateFormat;
20 | import java.util.Date;
21 |
22 | import javax.swing.BoxLayout;
23 | import javax.swing.JLabel;
24 | import javax.swing.JPanel;
25 |
26 | import org.apache.zookeeper.data.Stat;
27 |
28 | public class JZVStat extends JPanel {
29 | /** */
30 | private static final long serialVersionUID = 1L;
31 |
32 | private final JStatView aversion = new JStatView("aversion :");
33 | private final JStatView ctime = new JStatView("ctime :");
34 | private final JStatView cversion = new JStatView("cversion :");
35 | private final JStatView czxid = new JStatView("czxid :");
36 | private final JStatView dataLength = new JStatView("data length :");
37 | private final JStatView ephemeralOwner = new JStatView("ephemeral owner :");
38 | private final JStatView mtime = new JStatView("mtime :");
39 | private final JStatView mzxid = new JStatView("mzxid :");
40 | private final JStatView numChildren = new JStatView("numChildren :");
41 | private final JStatView pzxid = new JStatView("pzxid :");
42 | private final JStatView version = new JStatView("version :");
43 |
44 | private final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(
45 | DateFormat.SHORT, DateFormat.SHORT, this.getLocale());
46 |
47 | private class JStatView extends JPanel {
48 | /** */
49 | private static final long serialVersionUID = 1L;
50 | private final JLabel jlValue = new JLabel();
51 |
52 | public JStatView(String label) {
53 | super(new BorderLayout(2, 0));
54 | this.add(new JLabel(label), BorderLayout.WEST);
55 | this.add(this.jlValue);
56 | }
57 |
58 | public void setValue(String value) {
59 | this.jlValue.setText(value);
60 | this.doLayout();
61 | }
62 | }
63 |
64 | public JZVStat() {
65 | super();
66 | this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
67 | JPanel statsPane = new JPanel(new GridLayout(0, 2));
68 | statsPane.add(this.ctime);
69 | statsPane.add(this.mtime);
70 | statsPane.add(this.version);
71 | statsPane.add(this.aversion);
72 | statsPane.add(this.cversion);
73 | statsPane.add(this.czxid);
74 | statsPane.add(this.mzxid);
75 | statsPane.add(this.pzxid);
76 | statsPane.add(this.dataLength);
77 | statsPane.add(this.ephemeralOwner);
78 | statsPane.add(this.numChildren);
79 | this.add(statsPane);
80 | }
81 |
82 | private JPanel createStatPane(JStatView sView1, JStatView sView2,
83 | JStatView sView3, JStatView sView4) {
84 | JPanel statsPane = new JPanel(new GridLayout(3, 1));
85 | if (sView1 != null) {
86 | statsPane.add(sView1);
87 | }
88 | if (sView2 != null) {
89 | statsPane.add(sView2);
90 | }
91 | if (sView3 != null) {
92 | statsPane.add(sView3);
93 | }
94 | if (sView4 != null) {
95 | statsPane.add(sView4);
96 | }
97 | return statsPane;
98 | }
99 |
100 | public void setStat(Stat stat) {
101 | if (stat == null) {
102 | System.out.println("stat null");
103 | this.aversion.setValue("");
104 | this.ctime.setValue("");
105 | this.cversion.setValue("");
106 | this.czxid.setValue("");
107 | this.dataLength.setValue("");
108 | this.ephemeralOwner.setValue("");
109 | this.mtime.setValue("");
110 | this.mzxid.setValue("");
111 | this.numChildren.setValue("");
112 | this.pzxid.setValue("");
113 | this.version.setValue("");
114 | } else {
115 | System.out.println("stat = " + stat);
116 |
117 | this.aversion.setValue(String.valueOf(stat.getAversion()));
118 | this.ctime.setValue(this.DATE_FORMAT.format(new Date(stat
119 | .getCtime())));
120 | this.cversion.setValue(String.valueOf(stat.getCversion()));
121 | this.czxid.setValue(String.valueOf(stat.getCzxid()));
122 | this.dataLength.setValue(String.valueOf(stat.getDataLength()));
123 | this.ephemeralOwner.setValue(String.valueOf(stat
124 | .getEphemeralOwner()));
125 | this.mtime.setValue(this.DATE_FORMAT.format(new Date(stat
126 | .getMtime())));
127 | this.mzxid.setValue(String.valueOf(stat.getMzxid()));
128 | this.numChildren.setValue(String.valueOf(stat.getNumChildren()));
129 | this.pzxid.setValue(String.valueOf(stat.getPzxid()));
130 | this.version.setValue(String.valueOf(stat.getVersion()));
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/net/isammoc/zooviewer/node/ZVNode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This program is free software: you can redistribute it and/or modify
3 | * it under the terms of the GNU Lesser General Public License as published by
4 | * the Free Software Foundation, either version 3 of the License, or
5 | * (at your option) any later version.
6 | *
7 | * This program is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | * GNU Lesser General Public License for more details.
11 | *
12 | * You should have received a copy of the GNU Lesser General Public License
13 | * along with this program. If not, see .
14 | */
15 | package net.isammoc.zooviewer.node;
16 |
17 | import java.beans.PropertyChangeListener;
18 |
19 | import org.apache.zookeeper.data.Stat;
20 |
21 | /**
22 | * A ZVNode is a data fit requierements to be a ZooKeeper node.
23 | */
24 | public interface ZVNode {
25 | final String PROPERTY_DATA = "data";
26 | final String PROPERTY_EXISTS = "exists";
27 | final String PROPERTY_CHILDREN = "children";
28 | final String PROPERTY_STAT = "stat";
29 |
30 | /**
31 | * Returns this node's path.
32 | * @return the path
33 | */
34 | String getPath();
35 |
36 | /**
37 | * Returns this node's name.
38 | * @return the name
39 | */
40 | String getName();
41 |
42 | /**
43 | * Returns this node's data.
44 | * @return the data
45 | */
46 | byte[] getData();
47 |
48 | /**
49 | * Returns this node's stats.
50 | * @return the stats
51 | */
52 | Stat getStat();
53 |
54 | /**
55 | * Checks if this node exists in the ZooKeeper model.
56 | * @return
57 | */
58 | boolean exists();
59 |
60 | /**
61 | * Adds a {@link PropertyChangeListener} to this node's listeners list.
62 | * @param listener the listener
63 | */
64 | void addPropertyChangeListener(PropertyChangeListener listener);
65 |
66 | /**
67 | * Adds a {@link PropertyChangeListener} to this node's listeners list.
68 | *
69 | * @param propertyName the property name
70 | * @param listener the listener
71 | */
72 | void addPropertyChangeListener(String propertyName,
73 | PropertyChangeListener listener);
74 |
75 | /**
76 | * Remove the specified {@link PropertyChangeListener} from this node's listeners list.
77 | * @param listener the listener
78 | */
79 | void removePropertyChangeListener(PropertyChangeListener listener);
80 |
81 | /**
82 | * Remove the specified {@link PropertyChangeListener} from this node's listeners list.
83 | * @param the property name
84 | * @param listener the listener
85 | */
86 | void removePropertyChangeListener(String propertyName,
87 | PropertyChangeListener listener);
88 | }
--------------------------------------------------------------------------------
/src/main/java/net/isammoc/zooviewer/node/ZVNodeImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This program is free software: you can redistribute it and/or modify
3 | * it under the terms of the GNU Lesser General Public License as published by
4 | * the Free Software Foundation, either version 3 of the License, or
5 | * (at your option) any later version.
6 | *
7 | * This program is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | * GNU Lesser General Public License for more details.
11 | *
12 | * You should have received a copy of the GNU Lesser General Public License
13 | * along with this program. If not, see .
14 | */
15 | package net.isammoc.zooviewer.node;
16 |
17 | import java.beans.PropertyChangeListener;
18 | import java.beans.PropertyChangeSupport;
19 | import java.util.Arrays;
20 |
21 | import org.apache.zookeeper.data.Stat;
22 |
23 | public class ZVNodeImpl implements ZVNode {
24 |
25 | private final String path;
26 | private final String name;
27 | private boolean exists;
28 | private byte[] data;
29 | private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
30 | private Stat stat;
31 |
32 | public ZVNodeImpl(String path) {
33 | this.path = path;
34 | if ("/".equals(path)) {
35 | this.name = "/";
36 | } else {
37 | this.name = path.substring(path.lastIndexOf("/") + 1);
38 | }
39 | this.exists = false;
40 | }
41 |
42 | public ZVNodeImpl(String path, byte[] data) {
43 | this.path = path;
44 | if ("/".equals(path)) {
45 | this.name = "/";
46 | } else {
47 | this.name = path.substring(path.lastIndexOf("/") + 1);
48 | }
49 | this.data = (data == null ? null : Arrays.copyOf(data, data.length));
50 | this.exists = true;
51 | }
52 |
53 | @Override
54 | public String getPath() {
55 | return this.path;
56 | }
57 |
58 | @Override
59 | public String getName() {
60 | return this.name;
61 | }
62 |
63 | @Override
64 | public byte[] getData() {
65 | if (this.data == null) {
66 | return null;
67 | } else {
68 | return Arrays.copyOf(this.data, this.data.length);
69 | }
70 | }
71 |
72 | public void setData(byte[] data) {
73 | if (!Arrays.equals(this.data, data)) {
74 | byte[] old = this.data;
75 | this.data = (data == null ? null : Arrays.copyOf(data, data.length));
76 | this.pcs.firePropertyChange(PROPERTY_DATA, old, data);
77 | }
78 | }
79 |
80 | @Override
81 | public boolean exists() {
82 | return this.exists;
83 | }
84 |
85 | public void setExists(boolean newExists) {
86 | if (newExists != this.exists) {
87 | this.exists = newExists;
88 | this.pcs.firePropertyChange(PROPERTY_EXISTS, !this.exists,
89 | this.exists);
90 | }
91 | }
92 |
93 | @Override
94 | public void addPropertyChangeListener(PropertyChangeListener listener) {
95 | this.pcs.addPropertyChangeListener(listener);
96 | }
97 |
98 | @Override
99 | public void removePropertyChangeListener(PropertyChangeListener listener) {
100 | this.pcs.removePropertyChangeListener(listener);
101 | }
102 |
103 | @Override
104 | public void addPropertyChangeListener(String propertyName,
105 | PropertyChangeListener listener) {
106 | this.pcs.addPropertyChangeListener(propertyName, listener);
107 | }
108 |
109 | @Override
110 | public void removePropertyChangeListener(String propertyName,
111 | PropertyChangeListener listener) {
112 | this.pcs.removePropertyChangeListener(propertyName, listener);
113 | }
114 |
115 | @Override
116 | public boolean equals(Object obj) {
117 | if (obj == null) {
118 | return false;
119 | }
120 | if (this.getClass() != obj.getClass()) {
121 | return false;
122 | }
123 | ZVNodeImpl other = (ZVNodeImpl) obj;
124 | return this.path.equals(other.path);
125 | }
126 |
127 | @Override
128 | public int hashCode() {
129 | return this.path.hashCode();
130 | }
131 |
132 | @Override
133 | public String toString() {
134 | return String.format("ZVNodeImpl[path='%s', " + this.exists
135 | + ", length='%d']", this.path, (this.data == null ? -1
136 | : this.data.length));
137 | }
138 |
139 | @Override
140 | public Stat getStat() {
141 | return this.stat == null ? null : copyStat(this.stat);
142 | }
143 |
144 | public void setStat(Stat stat) {
145 | if (this.stat == null ? stat != null : !this.stat.equals(stat)) {
146 | Stat old = this.stat;
147 | this.stat = stat == null ? null : copyStat(stat);
148 | this.pcs.firePropertyChange(PROPERTY_STAT, old, stat);
149 | }
150 | }
151 |
152 | private static Stat copyStat(Stat stat) {
153 | return new Stat(stat.getCzxid(), stat.getMzxid(), stat.getCtime(),
154 | stat.getMtime(), stat.getVersion(), stat.getCversion(),
155 | stat.getAversion(), stat.getEphemeralOwner(),
156 | stat.getDataLength(), stat.getNumChildren(), stat.getPzxid());
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/main/java/net/isammoc/zooviewer/tree/JZVTree.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This program is free software: you can redistribute it and/or modify
3 | * it under the terms of the GNU Lesser General Public License as published by
4 | * the Free Software Foundation, either version 3 of the License, or
5 | * (at your option) any later version.
6 | *
7 | * This program is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | * GNU Lesser General Public License for more details.
11 | *
12 | * You should have received a copy of the GNU Lesser General Public License
13 | * along with this program. If not, see .
14 | */
15 | package net.isammoc.zooviewer.tree;
16 |
17 | import javax.swing.JTree;
18 |
19 | import net.isammoc.zooviewer.model.ZVModel;
20 | import net.isammoc.zooviewer.node.ZVNode;
21 |
22 | public class JZVTree extends JTree {
23 | /** */
24 | private static final long serialVersionUID = 1L;
25 |
26 | public JZVTree(ZVModel model) {
27 | super(new ZVTreeModel(model));
28 | }
29 |
30 | public JZVTree(ZVTreeModel model) {
31 | super(model);
32 | }
33 |
34 | @Override
35 | public String convertValueToText(Object value, boolean selected,
36 | boolean expanded, boolean leaf, int row, boolean hasFocus) {
37 | if (value instanceof ZVNode) {
38 | return ((ZVNode) value).getName();
39 | }
40 | return super.convertValueToText(value, selected, expanded, leaf, row,
41 | hasFocus);
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/net/isammoc/zooviewer/tree/ZVTreeModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This program is free software: you can redistribute it and/or modify
3 | * it under the terms of the GNU Lesser General Public License as published by
4 | * the Free Software Foundation, either version 3 of the License, or
5 | * (at your option) any later version.
6 | *
7 | * This program is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | * GNU Lesser General Public License for more details.
11 | *
12 | * You should have received a copy of the GNU Lesser General Public License
13 | * along with this program. If not, see .
14 | */
15 | package net.isammoc.zooviewer.tree;
16 |
17 | import java.util.StringTokenizer;
18 |
19 | import javax.swing.event.EventListenerList;
20 | import javax.swing.event.TreeModelEvent;
21 | import javax.swing.event.TreeModelListener;
22 | import javax.swing.tree.TreeModel;
23 | import javax.swing.tree.TreePath;
24 |
25 | import net.isammoc.zooviewer.model.ZVModel;
26 | import net.isammoc.zooviewer.model.ZVModelListener;
27 | import net.isammoc.zooviewer.node.ZVNode;
28 |
29 | public class ZVTreeModel implements TreeModel {
30 | /** Listeners. */
31 | protected EventListenerList listenerList = new EventListenerList();
32 | private final ZVModel model;
33 |
34 | public ZVTreeModel(ZVModel model) {
35 | this.model = model;
36 | model.addModelListener(new ZVModelListener() {
37 |
38 | @Override
39 | public void nodeDeleted(ZVNode oldNode, int oldIndex) {
40 | System.out.println("nodeDeleted : " + oldNode);
41 | ZVTreeModel.this.fireTreeNodesRemoved(this, ZVTreeModel.this
42 | .getTreePath(oldNode).getParentPath(),
43 | new int[] { oldIndex }, new Object[] { oldNode });
44 | }
45 |
46 | @Override
47 | public void nodeDataChanged(ZVNode node) {
48 | System.out.println("nodeDataChanged : " + node);
49 | // FLE+
50 | System.out.println("nodeDataChanged : " + node);
51 | TreePath parentPath = ZVTreeModel.this.getTreePath(node)
52 | .getParentPath();
53 | int index = ZVTreeModel.this.getIndexOfChild(
54 | parentPath.getLastPathComponent(), node);
55 | ZVTreeModel.this.fireTreeNodesChanged(this,
56 | parentPath.getPath(), new int[] { index },
57 | new Object[] { node });
58 | }
59 |
60 | @Override
61 | public void nodeCreated(ZVNode newNode) {
62 | System.out.println("nodeCreated : " + newNode);
63 | if (newNode == ZVTreeModel.this.getRoot()) {
64 | ZVTreeModel.this.fireTreeStructureChanged(this,
65 | new TreePath(newNode));
66 | } else {
67 | try {
68 | TreePath treePath = ZVTreeModel.this.getTreePath(
69 | newNode).getParentPath();
70 | ZVTreeModel.this.fireTreeNodesInserted(this, treePath,
71 | new int[] { ZVTreeModel.this.getIndexOfChild(
72 | treePath.getLastPathComponent(),
73 | newNode) }, new Object[] { newNode });
74 | // System.out.println("fire done");
75 | } catch (Exception e) {
76 | e.printStackTrace();
77 | }
78 | }
79 | }
80 | });
81 | }
82 |
83 | public TreePath getTreePath(ZVNode node) {
84 | String path = node.getPath();
85 | TreePath treePath = new TreePath(this.model.getNode("/"));
86 | String currentPath = "";
87 | StringTokenizer st = new StringTokenizer(path, "/", false);
88 | while (st.hasMoreTokens()) {
89 | currentPath += "/" + st.nextToken();
90 | treePath = treePath.pathByAddingChild(this.model
91 | .getNode(currentPath));
92 | }
93 | return treePath;
94 | }
95 |
96 | @Override
97 | public ZVNode getRoot() {
98 | return this.model.getNode("/");
99 | }
100 |
101 | @Override
102 | public ZVNode getChild(Object parent, int index) {
103 | if (!(parent instanceof ZVNode)) {
104 | throw new IllegalArgumentException("parent must be a ZVNode");
105 | }
106 |
107 | return this.model.getChildren((ZVNode) parent).get(index);
108 | }
109 |
110 | @Override
111 | public int getChildCount(Object parent) {
112 | if (!(parent instanceof ZVNode)) {
113 | throw new IllegalArgumentException("parent must be a ZVNode");
114 | }
115 |
116 | return this.model.getChildren((ZVNode) parent).size();
117 | }
118 |
119 | @Override
120 | public boolean isLeaf(Object node) {
121 | if (!(node instanceof ZVNode)) {
122 | throw new IllegalArgumentException("node must be a ZVNode");
123 | }
124 |
125 | return this.model.getChildren((ZVNode) node).size() == 0;
126 | }
127 |
128 | @Override
129 | public void valueForPathChanged(TreePath path, Object newValue) {
130 | throw new UnsupportedOperationException("Can't change data");
131 | }
132 |
133 | @Override
134 | public int getIndexOfChild(Object parent, Object child) {
135 | if (!(parent instanceof ZVNode)) {
136 | throw new IllegalArgumentException("parent must be a ZVNode");
137 | }
138 | if (!(child instanceof ZVNode)) {
139 | throw new IllegalArgumentException("child must be a ZVNode");
140 | }
141 | return this.model.getChildren((ZVNode) parent).indexOf(child);
142 | }
143 |
144 | /**
145 | * Adds a listener for the TreeModelEvent posted after the tree changes.
146 | *
147 | * @see #removeTreeModelListener
148 | * @param l
149 | * the listener to add
150 | */
151 | @Override
152 | public void addTreeModelListener(TreeModelListener l) {
153 | this.listenerList.add(TreeModelListener.class, l);
154 | }
155 |
156 | /**
157 | * Removes a listener previously added with addTreeModelListener().
158 | *
159 | * @see #addTreeModelListener
160 | * @param l
161 | * the listener to remove
162 | */
163 | @Override
164 | public void removeTreeModelListener(TreeModelListener l) {
165 | this.listenerList.remove(TreeModelListener.class, l);
166 | }
167 |
168 | /**
169 | * Notifies all listeners that have registered interest for notification on
170 | * this event type. The event instance is lazily created using the
171 | * parameters passed into the fire method.
172 | *
173 | * @param source
174 | * the node being changed
175 | * @param path
176 | * the path to the root node
177 | * @param childIndices
178 | * the indices of the changed elements
179 | * @param children
180 | * the changed elements
181 | * @see EventListenerList
182 | */
183 | protected void fireTreeNodesChanged(Object source, Object[] path,
184 | int[] childIndices, Object[] children) {
185 | // Guaranteed to return a non-null array
186 | Object[] listeners = this.listenerList.getListenerList();
187 | TreeModelEvent e = null;
188 | // Process the listeners last to first, notifying
189 | // those that are interested in this event
190 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
191 | if (listeners[i] == TreeModelListener.class) {
192 | // Lazily create the event:
193 | if (e == null) {
194 | e = new TreeModelEvent(source, path, childIndices, children);
195 | }
196 | ((TreeModelListener) listeners[i + 1]).treeNodesChanged(e);
197 | }
198 | }
199 | }
200 |
201 | /**
202 | * Notifies all listeners that have registered interest for notification on
203 | * this event type. The event instance is lazily created using the
204 | * parameters passed into the fire method.
205 | *
206 | * @param source
207 | * the node where new elements are being inserted
208 | * @param path
209 | * the path to the root node
210 | * @param childIndices
211 | * the indices of the new elements
212 | * @param children
213 | * the new elements
214 | * @see EventListenerList
215 | */
216 | protected void fireTreeNodesInserted(Object source, TreePath path,
217 | int[] childIndices, Object[] children) {
218 | // Guaranteed to return a non-null array
219 | Object[] listeners = this.listenerList.getListenerList();
220 | TreeModelEvent e = null;
221 | // Process the listeners last to first, notifying
222 | // those that are interested in this event
223 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
224 | if (listeners[i] == TreeModelListener.class) {
225 | // Lazily create the event:
226 | if (e == null) {
227 | e = new TreeModelEvent(source, path, childIndices, children);
228 | }
229 | ((TreeModelListener) listeners[i + 1]).treeNodesInserted(e);
230 | }
231 | }
232 | }
233 |
234 | /**
235 | * Notifies all listeners that have registered interest for notification on
236 | * this event type. The event instance is lazily created using the
237 | * parameters passed into the fire method.
238 | *
239 | * @param source
240 | * the node where elements are being removed
241 | * @param path
242 | * the path to the root node
243 | * @param childIndices
244 | * the indices of the removed elements
245 | * @param children
246 | * the removed elements
247 | * @see EventListenerList
248 | */
249 | protected void fireTreeNodesRemoved(Object source, TreePath treePath,
250 | int[] indexes, Object[] objects) {
251 | // Guaranteed to return a non-null array
252 | Object[] listeners = this.listenerList.getListenerList();
253 | TreeModelEvent e = null;
254 | // Process the listeners last to first, notifying
255 | // those that are interested in this event
256 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
257 | if (listeners[i] == TreeModelListener.class) {
258 | // Lazily create the event:
259 | if (e == null) {
260 | e = new TreeModelEvent(source, treePath, indexes, objects);
261 | }
262 | ((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e);
263 | }
264 | }
265 | }
266 |
267 | /**
268 | * Notifies all listeners that have registered interest for notification on
269 | * this event type. The event instance is lazily created using the
270 | * parameters passed into the fire method.
271 | *
272 | * @param source
273 | * the node where the tree model has changed
274 | * @param path
275 | * the path to the root node
276 | * @param childIndices
277 | * the indices of the affected elements
278 | * @param children
279 | * the affected elements
280 | * @see EventListenerList
281 | */
282 | protected void fireTreeStructureChanged(Object source, Object[] path,
283 | int[] childIndices, Object[] children) {
284 | // Guaranteed to return a non-null array
285 | Object[] listeners = this.listenerList.getListenerList();
286 | TreeModelEvent e = null;
287 | // Process the listeners last to first, notifying
288 | // those that are interested in this event
289 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
290 | if (listeners[i] == TreeModelListener.class) {
291 | // Lazily create the event:
292 | if (e == null) {
293 | e = new TreeModelEvent(source, path, childIndices, children);
294 | }
295 | ((TreeModelListener) listeners[i + 1]).treeStructureChanged(e);
296 | }
297 | }
298 | }
299 |
300 | /*
301 | * Notifies all listeners that have registered interest for notification on
302 | * this event type. The event instance is lazily created using the
303 | * parameters passed into the fire method.
304 | *
305 | * @param source the node where the tree model has changed
306 | *
307 | * @param path the path to the root node
308 | *
309 | * @see EventListenerList
310 | */
311 | private void fireTreeStructureChanged(Object source, TreePath path) {
312 | // Guaranteed to return a non-null array
313 | Object[] listeners = this.listenerList.getListenerList();
314 | TreeModelEvent e = null;
315 | // Process the listeners last to first, notifying
316 | // those that are interested in this event
317 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
318 | if (listeners[i] == TreeModelListener.class) {
319 | // Lazily create the event:
320 | if (e == null) {
321 | e = new TreeModelEvent(source, path);
322 | }
323 | ((TreeModelListener) listeners[i + 1]).treeStructureChanged(e);
324 | }
325 | }
326 | }
327 |
328 | }
329 |
--------------------------------------------------------------------------------
/src/main/resources/net/isammoc/zooviewer/App.properties:
--------------------------------------------------------------------------------
1 | start.connection.title=ZooKeeper server connection
2 | start.connection.message=Enter the connection string
3 | start.connection.aborted.message=Connection aborted by user.
4 |
--------------------------------------------------------------------------------
/src/main/resources/net/isammoc/zooviewer/node/JZVNode.properties:
--------------------------------------------------------------------------------
1 | btn.delete=Delete
2 | btn.delete.action=delete.node
3 | btn.add.child=Add child
4 | btn.add.child.action=add.child
5 | btn.update=Update
6 | btn.update.action=update.node
7 | pnl.stat=Stat
8 | pnl.data=Data
9 | pnl.new.child=New child
10 | pnl.new.child.lbl.name=Name :
11 | pnl.new.child.lbl.data=Data :
12 | dlg.error.addWithoutName=Can't add a node without name
13 | dlg.error.deleteWithoutSelection=Cannotr update node without selection
14 | dlg.error.title=Error
--------------------------------------------------------------------------------