1 3 27 28 30 package de.qfs.apps.qflog.logview; 31 32 34 import java.awt.BorderLayout ; 35 import java.awt.Component ; 36 import java.awt.Frame ; 37 import java.awt.Window ; 38 import java.awt.event.ActionEvent ; 39 import java.awt.event.KeyEvent ; 40 import java.awt.event.MouseAdapter ; 41 import java.awt.event.MouseEvent ; 42 43 import java.util.ResourceBundle ; 44 45 import javax.swing.Action ; 46 import javax.swing.AbstractAction ; 47 import javax.swing.BorderFactory ; 48 import javax.swing.Icon ; 49 import javax.swing.KeyStroke ; 50 import javax.swing.JLabel ; 51 import javax.swing.JMenu ; 52 import javax.swing.JMenuItem ; 53 import javax.swing.JPanel ; 54 import javax.swing.JPopupMenu ; 55 import javax.swing.JScrollPane ; 56 import javax.swing.JTree ; 57 import javax.swing.SwingUtilities ; 58 import javax.swing.tree.DefaultTreeCellRenderer ; 59 import javax.swing.tree.TreePath ; 60 61 import de.qfs.lib.gui.SwingUtil; 62 import de.qfs.lib.gui.WindowsTreeCellRenderer; 63 import de.qfs.lib.log.Log; 64 import de.qfs.lib.log.Logger; 65 import de.qfs.lib.option.OptionDialog; 66 import de.qfs.lib.util.MapResourceBundle; 67 68 70 91 public class LogLevelView 92 extends JPanel 93 { 94 96 99 private final static Logger logger = new Logger (LogLevelView.class); 100 101 104 private transient LogLevelTreeModel model; 105 106 109 private transient boolean initialized; 110 111 114 private transient JTree tree; 115 116 119 private transient MapResourceBundle resources; 120 121 124 private transient JPopupMenu popup; 125 126 129 private transient PopupListener popupListener; 130 131 134 private OptionDialog optionDialog; 135 136 139 private boolean logging; 140 141 147 private Action removeAction; 148 149 152 private Action removeRecursiveAction; 153 154 157 private Action setERRAction; 158 159 162 private Action setERRDETAILAction; 163 164 167 private Action setWRNAction; 168 169 172 private Action setWRNDETAILAction; 173 174 177 private Action setMSGAction; 178 179 182 private Action setMSGDETAILAction; 183 184 187 private Action setMTDAction; 188 189 192 private Action setMTDDETAILAction; 193 194 197 private Action setDBGAction; 198 199 202 private Action setDBGDETAILAction; 203 204 207 private Action expandAllAction; 208 209 212 private Action collapseAllAction; 213 214 217 private Action showSetLevelsAction; 218 219 222 private Action editOptionsAction; 223 224 226 228 233 public LogLevelView(LogLevelTreeModel model) 234 { 235 boolean excluded = ! logging; 236 if (excluded) { 237 Log.excludeThread(); 238 } 239 try { 240 this.model = model; 241 resources = new MapResourceBundle (); 242 resources.fetchProperties 243 ("/de/qfs/apps/qflog/logview/resources/properties/loglevelview", 244 LogLevelView.class); 245 model.setRootName(resources.getString("logLevelView.root.name", 246 "default")); 247 } finally { 248 if (excluded) { 249 Log.includeThread(); 250 } 251 } 252 } 253 254 256 258 270 public final void setLoggingEnabled(boolean enable) 271 { 272 logging = enable; 273 model.setLoggingEnabled(enable); 274 } 275 276 278 283 288 public void init() 289 { 290 if (initialized) { 291 return; 292 } 293 initialized = true; 294 295 boolean excluded = ! logging; 296 if (excluded) { 297 Log.excludeThread(); 298 } 299 try { 300 setLayout(new BorderLayout ()); 301 setBorder(null); 302 303 JPanel top = new JPanel (); 304 top.setLayout(new BorderLayout ()); 305 top.setBorder(null); 306 307 String title = resources.getString("logLevelView.title", 308 "Log levels"); 309 JLabel titleLabel = new JLabel (title); 310 titleLabel.setBorder(BorderFactory.createEtchedBorder()); 311 top.add(titleLabel, BorderLayout.NORTH); 312 313 tree = new JTree (model) { 314 public boolean hasBeenExpanded(TreePath path) { 315 return false; 316 } 317 }; 318 tree.setBorder(null); 319 tree.setCellRenderer(new Renderer ()); 320 321 JScrollPane treePane = new JScrollPane (tree); 322 SwingUtil.constrainScroll(treePane); 323 treePane.setBorder(BorderFactory.createLoweredBevelBorder()); 324 top.add(treePane, BorderLayout.CENTER); 325 add(top, BorderLayout.CENTER); 326 327 tree.setSelectionRow(0); 329 330 setupActions(); 332 333 tree.registerKeyboardAction 334 (removeAction, "remove", 335 KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), 336 tree.WHEN_FOCUSED); 337 tree.registerKeyboardAction 338 (removeRecursiveAction, "removeRecursive", 339 KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 340 KeyEvent.CTRL_MASK), 341 tree.WHEN_FOCUSED); 342 343 tree.registerKeyboardAction 344 (setERRAction, "setERR", 345 KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), 346 tree.WHEN_FOCUSED); 347 tree.registerKeyboardAction 348 (setERRDETAILAction, "setERRDETAIL", 349 KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), 350 tree.WHEN_FOCUSED); 351 tree.registerKeyboardAction 352 (setWRNAction, "setWRN", 353 KeyStroke.getKeyStroke(KeyEvent.VK_3, 0), 354 tree.WHEN_FOCUSED); 355 tree.registerKeyboardAction 356 (setWRNDETAILAction, "setWRNDETAIL", 357 KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), 358 tree.WHEN_FOCUSED); 359 tree.registerKeyboardAction 360 (setMSGAction, "MSGERR", 361 KeyStroke.getKeyStroke(KeyEvent.VK_5, 0), 362 tree.WHEN_FOCUSED); 363 tree.registerKeyboardAction 364 (setMSGDETAILAction, "setMSGDETAIL", 365 KeyStroke.getKeyStroke(KeyEvent.VK_6, 0), 366 tree.WHEN_FOCUSED); 367 tree.registerKeyboardAction 368 (setMTDAction, "setMTD", 369 KeyStroke.getKeyStroke(KeyEvent.VK_7, 0), 370 tree.WHEN_FOCUSED); 371 tree.registerKeyboardAction 372 (setMTDDETAILAction, "setMTDDETAIL", 373 KeyStroke.getKeyStroke(KeyEvent.VK_8, 0), 374 tree.WHEN_FOCUSED); 375 tree.registerKeyboardAction 376 (setDBGAction, "setDBG", 377 KeyStroke.getKeyStroke(KeyEvent.VK_9, 0), 378 tree.WHEN_FOCUSED); 379 tree.registerKeyboardAction 380 (setDBGDETAILAction, "setDBGDETAIL", 381 KeyStroke.getKeyStroke(KeyEvent.VK_0, 0), 382 tree.WHEN_FOCUSED); 383 384 tree.registerKeyboardAction 385 (expandAllAction, "expandAll", 386 KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.ALT_MASK), 387 tree.WHEN_FOCUSED); 388 389 tree.registerKeyboardAction 390 (collapseAllAction, "collapseAll", 391 KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.ALT_MASK), 392 tree.WHEN_FOCUSED); 393 394 popup = new JPopupMenu (); 396 fillMenu(popup); 397 popupListener = new PopupListener (); 398 tree.addMouseListener(popupListener); 399 400 showSetLevels(); 401 } finally { 402 if (excluded) { 403 Log.includeThread(); 404 } 405 } 406 } 407 408 411 415 public void cleanup() 416 { 417 if (logging && logger.level >= Log.MTD) { 418 logger.log(Log.MTD, "cleanup()", ""); 419 } 420 421 SwingUtil.cleanup(this); 422 423 tree.removeMouseListener(popupListener); 424 popupListener = null; 425 SwingUtil.cleanup(popup); 426 popup = null; 427 428 tree.resetKeyboardActions(); 429 tree = null; 430 resources = null; 431 432 model.cleanup(); 433 model = null; 434 } 435 436 439 442 public void finalize() 443 { 444 if (logging && logger.level >= Log.MTD) { 445 logger.log(Log.MTD, "finalize()", ""); 446 } 447 } 448 449 451 456 461 public final LogLevelTreeModel getModel() 462 { 463 return model; 464 } 465 466 469 474 public final JTree getTree() 475 { 476 return tree; 477 } 478 479 482 487 public void fillMenu(JMenu menu) 488 { 489 menu.add(removeAction); 490 menu.add(removeRecursiveAction); 491 492 menu.addSeparator(); 493 494 menu.add(setERRAction); 495 menu.add(setERRDETAILAction); 496 menu.add(setWRNAction); 497 menu.add(setWRNDETAILAction); 498 menu.add(setMSGAction); 499 menu.add(setMSGDETAILAction); 500 menu.add(setMTDAction); 501 menu.add(setMTDDETAILAction); 502 menu.add(setDBGAction); 503 menu.add(setDBGDETAILAction); 504 505 menu.addSeparator(); 506 507 menu.add(showSetLevelsAction); 508 509 menu.addSeparator(); 510 511 JMenuItem mi = menu.add(editOptionsAction); 512 String mnemo = resources.getString 513 ("logLevelView.action.editOptions.mnemonic", null); 514 if (mnemo != null) { 515 mi.setMnemonic(mnemo.charAt(0)); 516 } 517 } 518 519 524 public void fillMenu(JPopupMenu menu) 525 { 526 menu.add(removeAction); 527 menu.add(removeRecursiveAction); 528 529 menu.addSeparator(); 530 531 menu.add(setERRAction); 532 menu.add(setERRDETAILAction); 533 menu.add(setWRNAction); 534 menu.add(setWRNDETAILAction); 535 menu.add(setMSGAction); 536 menu.add(setMSGDETAILAction); 537 menu.add(setMTDAction); 538 menu.add(setMTDDETAILAction); 539 menu.add(setDBGAction); 540 menu.add(setDBGDETAILAction); 541 542 menu.addSeparator(); 543 544 menu.add(showSetLevelsAction); 545 546 menu.addSeparator(); 547 548 menu.add(editOptionsAction); 549 } 550 551 553 558 564 public void setResources(ResourceBundle rb) 565 { 566 resources.addResources(rb); 567 } 568 569 570 573 577 public void showSetLevels() 578 { 579 SwingUtilities.invokeLater(new Runnable () { 580 public void run() { 581 showSetLevelsAction.actionPerformed(null); 582 } 583 }); 584 } 585 586 588 593 596 private void setupActions() 597 { 598 if (removeAction == null) { 600 removeAction = new RemoveLevelAction (false); 601 setActionProperties(removeAction, "removeLevel"); 602 removeRecursiveAction = new RemoveLevelAction (true); 603 setActionProperties(removeRecursiveAction, "removeLevelRecursive"); 604 605 setERRAction = new ChangeLevelAction (Log.ERR); 606 setActionProperties(setERRAction, "setLevelERR"); 607 setERRDETAILAction = new ChangeLevelAction (Log.ERRDETAIL); 608 setActionProperties(setERRDETAILAction, "setLevelERRDETAIL"); 609 setWRNAction = new ChangeLevelAction (Log.WRN); 610 setActionProperties(setWRNAction, "setLevelWRN"); 611 setWRNDETAILAction = new ChangeLevelAction (Log.WRNDETAIL); 612 setActionProperties(setWRNDETAILAction, "setLevelWRNDETAIL"); 613 setMSGAction = new ChangeLevelAction (Log.MSG); 614 setActionProperties(setMSGAction, "setLevelMSG"); 615 setMSGDETAILAction = new ChangeLevelAction (Log.MSGDETAIL); 616 setActionProperties(setMSGDETAILAction, "setLevelMSGDETAIL"); 617 setMTDAction = new ChangeLevelAction (Log.MTD); 618 setActionProperties(setMTDAction, "setLevelMTD"); 619 setMTDDETAILAction = new ChangeLevelAction (Log.MTDDETAIL); 620 setActionProperties(setMTDDETAILAction, "setLevelMTDDETAIL"); 621 setDBGAction = new ChangeLevelAction (Log.DBG); 622 setActionProperties(setDBGAction, "setLevelDBG"); 623 setDBGDETAILAction = new ChangeLevelAction (Log.DBGDETAIL); 624 setActionProperties(setDBGDETAILAction, "setLevelDBGDETAIL"); 625 626 expandAllAction = new AbstractAction () { 627 public void actionPerformed(ActionEvent e) { 628 TreePath path = tree.getSelectionPath(); 629 if (path != null) { 630 boolean excluded = ! logging; 631 if (excluded) { 632 Log.excludeThread(); 633 } 634 try { 635 SwingUtil.expandAll(tree, path); 636 } finally { 637 if (excluded) { 638 Log.includeThread(); 639 } 640 } 641 } 642 } 643 }; 644 645 collapseAllAction = new AbstractAction () { 646 public void actionPerformed(ActionEvent e) { 647 TreePath path = tree.getSelectionPath(); 648 if (path != null) { 649 boolean excluded = ! logging; 650 if (excluded) { 651 Log.excludeThread(); 652 } 653 try { 654 SwingUtil.collapseAll(tree, path); 655 } finally { 656 if (excluded) { 657 Log.includeThread(); 658 } 659 } 660 } 661 } 662 }; 663 664 showSetLevelsAction = new ShowSetLevelsAction (); 665 setActionProperties(showSetLevelsAction, "showSetLevels"); 666 667 editOptionsAction = new AbstractAction () { 668 public void actionPerformed (ActionEvent e) { 669 editOptions(); 670 } 671 }; 672 setActionProperties(editOptionsAction, 673 "editOptions"); 674 675 } 676 } 677 678 681 687 private void setActionProperties(Action action, String resource) 688 { 689 String name = resources.getString 690 ("logLevelView.action." + resource + ".name", null); 691 if (name != null) { 692 action.putValue(Action.NAME, name); 693 } 694 695 String iconName = resources.getString 696 ("logLevelView.action." + resource + ".icon", null); 697 if (iconName != null) { 698 Icon icon = resources.getIcon (iconName, null); 699 if (icon != null) { 700 action.putValue(Action.SMALL_ICON, icon); 701 } 702 } 703 } 704 705 708 711 private void editOptions() 712 { 713 if (logging && logger.level >= Log.MTD) { 714 logger.log(Log.MTD, "editOptions()", ""); 715 } 716 717 boolean excluded = ! logging; 718 if (excluded) { 719 Log.excludeThread(); 720 } 721 try { 722 Frame frame; 723 Window win = SwingUtilities.windowForComponent(this); 724 if (win instanceof Frame ) { 725 frame = (Frame ) win; 726 } else { 727 frame = new Frame (); 729 } 730 if (optionDialog == null) { 731 optionDialog = new OptionDialog 732 (frame, resources.getString 733 ("logLevelView.optionDialog.title", "MISSING"), 734 model.getOptions(), "levelview"); 735 } else { 736 optionDialog.update(model.getOptions()); 737 } 738 optionDialog.setLocationRelativeTo(this); 739 optionDialog.doModal(); 740 } finally { 741 if (excluded) { 742 Log.includeThread(); 743 } 744 } 745 } 746 747 749 754 757 private class ChangeLevelAction 758 extends AbstractAction 759 { 760 763 private int level; 764 765 767 772 public ChangeLevelAction(int level) 773 { 774 this.level = level; 775 } 776 777 779 781 786 public void actionPerformed (ActionEvent e) 787 { 788 TreePath [] paths = tree.getSelectionPaths(); 789 790 if (paths != null) { 791 for (int i = 0; i < paths.length; i++) { 792 model.setLogLevel(paths[i], level); 793 } 794 } 795 } 796 797 } 799 800 803 806 private class RemoveLevelAction 807 extends AbstractAction 808 { 809 812 private boolean recurse; 813 814 816 821 public RemoveLevelAction(boolean recurse) 822 { 823 this.recurse = recurse; 824 } 825 826 828 830 835 public void actionPerformed (ActionEvent e) 836 { 837 TreePath [] paths = tree.getSelectionPaths(); 838 839 if (paths != null) { 840 for (int i = 0; i < paths.length; i++) { 841 model.removeLogLevel(paths[i], recurse); 842 } 843 } 844 } 845 846 } 848 849 852 856 private class ShowSetLevelsAction 857 extends AbstractAction 858 { 859 861 864 public ShowSetLevelsAction() 865 { 866 } 867 868 870 872 877 public void actionPerformed (ActionEvent e) 878 { 879 boolean excluded = !logging; 880 if (excluded) { 881 Log.excludeThread(); 882 } 883 try { 884 maybeExpandPath(new TreePath (new Object [] {model.getRoot()})); 885 } finally { 886 if (excluded) { 887 Log.includeThread(); 888 } 889 } 890 } 891 892 895 904 private boolean maybeExpandPath(TreePath path) 905 { 906 if (logging && logger.level >= Log.MTD) { 907 logger.log(Log.MTD, "maybeExpandPath(TreePath)", 908 logger.level < Log.MTDDETAIL ? "" : 909 "path: " + path); 910 } 911 Object node = path.getLastPathComponent(); 912 boolean isLevel = model.getLevel(node) != null; 913 boolean expand = false; 914 if (model.isLeaf(node)) { 915 return isLevel; 916 } 917 918 int num = model.getChildCount(node); 919 for (int i = 0; i < num; i++) { 920 Object child = model.getChild(node, i); 921 if (maybeExpandPath(path.pathByAddingChild(child))) { 922 expand = true; 923 } 924 } 925 if (logger.level >= Log.DBG) { 926 logger.log(Log.DBG, "maybeExpandPath(TreePath)", 927 "expand: " + expand); 928 } 929 930 if (expand) { 931 tree.expandPath(path); 932 } else { 933 tree.collapsePath(path); 934 } 935 return expand || isLevel; 936 } 937 938 } 940 941 943 948 951 class PopupListener 952 extends MouseAdapter 953 { 954 959 public void mousePressed(MouseEvent event) 960 { 961 maybePopup(event); 962 } 963 964 969 public void mouseReleased(MouseEvent event) 970 { 971 maybePopup(event); 972 } 973 974 982 private void maybePopup(MouseEvent event) 983 { 984 boolean excluded = !logging; 985 if (excluded) { 986 Log.excludeThread(); 987 } 988 try { 989 if (event.isPopupTrigger()) { 990 int row = 991 tree.getRowForLocation(event.getX(), event.getY()); 992 if (row >= 0) { 993 if (! tree.isRowSelected(row)) { 994 tree.setSelectionRow(row); 995 } 996 } else if (tree.isSelectionEmpty()) { 997 return; 999 } 1000 SwingUtil.showPopup(popup, tree, 1001 event.getX(), event.getY(), 1002 false); 1003 } 1004 } finally { 1005 if (excluded) { 1006 Log.includeThread(); 1007 } 1008 } 1009 } 1010 } 1011 1012 1014 1019 1021 1024 private final static int CLASS = 10; 1025 1026 1029 private final static int PACKAGE = 11; 1030 1031 1034 private final static int PACKAGE_OPEN = 12; 1035 1036 1039 private final static String iconNames[] = { 1040 "logLevelView.icon.err", "logLevelView.icon.errDetail", 1041 "logLevelView.icon.wrn", "logLevelView.icon.wrnDetail", 1042 "logLevelView.icon.msg", "logLevelView.icon.msgDetail", 1043 "logLevelView.icon.mtd", "logLevelView.icon.mtdDetail", 1044 "logLevelView.icon.dbg", "logLevelView.icon.dbgDetail", 1045 "logLevelView.icon.class", 1046 "logLevelView.icon.package", "logLevelView.icon.packageOpen" 1047 }; 1048 1049 1052 private final static Icon [] icons = new Icon [iconNames.length]; 1053 1054 1056 1060 private class Renderer 1061 extends WindowsTreeCellRenderer 1062 { 1063 1065 1068 public Renderer () 1069 { 1070 initIcons(); 1071 } 1072 1073 1075 1077 1090 public Component getTreeCellRendererComponent 1091 (JTree tree, Object obj, boolean selected, boolean expanded, 1092 boolean leaf, int row, boolean hasFocus) 1093 { 1094 JLabel com = (JLabel ) super.getTreeCellRendererComponent 1095 (tree, obj, selected, expanded, leaf, row, hasFocus); 1096 1097 Integer level = model.getLevel(obj); 1098 1099 int icon = leaf 1100 ? CLASS 1101 : (expanded ? PACKAGE_OPEN : PACKAGE); 1102 if (level == null) { 1103 com.setIcon(icons[icon]); 1104 return com; 1105 } 1106 int lvl = level.intValue(); 1107 if (lvl < Log.ERR || lvl > Log.DBGDETAIL) { 1108 com.setIcon(icons[icon]); 1109 } else { 1110 com.setIcon(icons[level.intValue() - 1]); 1111 } 1112 return com; 1113 } 1114 1115 1118 1121 private void initIcons() 1122 { 1123 if (icons[0] == null) { 1124 for (int i = 0; i < icons.length; i++) { 1125 icons[i] = resources.getIcon(iconNames[i], null); 1126 } 1127 } 1128 } 1129 1130 } 1132 1133 } 1135 | Popular Tags |