001: package tide.editor.completions;
002:
003: import tide.project.JDocRes;
004: import tide.editor.Accelerators;
005: import tide.bytecode.DecompileManager;
006: import javax.swing.table.DefaultTableModel;
007: import tide.editor.MainEditorFrame;
008: import snow.sortabletable.*;
009: import tide.utils.SyntaxUtils;
010: import tide.classsyntax.*;
011: import snow.utils.StringUtils;
012: import snow.html.HTMLUtils;
013: import java.util.*;
014: import java.awt.BorderLayout;
015: import java.awt.EventQueue;
016: import java.awt.event.*;
017: import javax.swing.*;
018: import javax.swing.event.*;
019: import javax.swing.text.*;
020: import javax.swing.text.html.*;
021: import java.io.*;
022: import java.lang.reflect.*;
023:
024: /** Presents the arguments for a single constructor or method name.
025: * => shows several items if various parameters as in "String.valueOf(".
026: * this dialog don't offers completion but a help on arguments, which are selected!
027: * IDEA: simply be not modal, just listen to "esc" and ")" typed and close.
028: */
029: public final class ArgumentsCompletionDialog extends JDialog implements
030: CompletionDialog {
031: final int fontSize = UIManager.getFont("Label.font").getSize();
032: final private CompletionModel cm = new CompletionModel();
033: private final SortableTableModel stm = new SortableTableModel(cm);
034: final private AdvancedSearchPanel asp = new AdvancedSearchPanel("",
035: null, stm, false);
036: private final JTable table = new JTable(stm);
037: private final JEditorPane javaDocPane = new JEditorPane();
038: private final JSplitPane sp;
039: private final JCheckBox viewInherited = new JCheckBox(
040: "View inherited", true);
041: private final JCheckBox viewDeprecated = new JCheckBox(
042: "View deprecated", true);
043: private final JCheckBox viewOnlyPublic = new JCheckBox(
044: "Only public", false);
045: private final JCheckBox viewDoc = new JCheckBox("Doc", true);
046: private final JEditorPane memberExplorerPane = new JEditorPane();
047: private final JTabbedPane explPane = new JTabbedPane();
048:
049: private final CompletionManager completionManager;
050: final private CaretListener caretListener;
051: final private int docOffset;
052:
053: final private HyperlinkListener hyperlinkListener; //todo
054: private boolean wasCancelled = true; // BAD NAME
055: private boolean wasClosed = false;
056:
057: transient AttrCompletionItem actualDisplayedItem = null;
058: private File browserLastBase = null;
059:
060: public ArgumentsCompletionDialog(String title, JFrame owner, int x,
061: int y, final CompletionManager completionManager,
062: final int docOffset) {
063: super (owner, title, false);
064: this .setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
065:
066: this .completionManager = completionManager;
067: this .docOffset = docOffset;
068:
069: setLayout(new BorderLayout(0, 0));
070:
071: JPanel tablePanel = new JPanel(new BorderLayout(0, 0));
072: tablePanel.add(new JScrollPane(table), BorderLayout.CENTER);
073:
074: stm.setSortedColumnAndOrder(-1, true); // avoid sorting.
075:
076: table.getSelectionModel().setSelectionMode(
077: ListSelectionModel.SINGLE_SELECTION);
078: //table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
079: //table.getColumnModel().getColumn(0).setPreferredWidth(100);
080:
081: UniversalTableCellRenderer ute = new UniversalTableCellRenderer(
082: stm);
083: table.setDefaultRenderer(Object.class, ute);
084:
085: tablePanel.add(asp, BorderLayout.NORTH);
086: stm.installGUI(table);
087: stm.setPreferredColumnSizesFromModel();
088:
089: ActionListener update = new ActionListener() {
090: public void actionPerformed(ActionEvent ae) {
091: cm.filter(viewInherited.isSelected(), viewDeprecated
092: .isSelected(), viewOnlyPublic.isSelected());
093: }
094: };
095:
096: asp.add(viewInherited);
097: viewInherited.addActionListener(update);
098: asp.add(viewDeprecated);
099: viewDeprecated.addActionListener(update);
100: asp.add(viewOnlyPublic);
101: viewOnlyPublic.addActionListener(update);
102: asp.add(viewDoc);
103: viewDoc.addActionListener(new ActionListener() {
104: public void actionPerformed(ActionEvent ae) {
105: MainEditorFrame.instance.globalProperties
106: .setBoolean("ViewJavaDocInCompletion", viewDoc
107: .isSelected());
108: explPane.setVisible(viewDoc.isSelected());
109: int dl = MainEditorFrame.instance.globalProperties
110: .getInteger("ArgumentsCompletionDialog_divloc",
111: fontSize * 30);
112: if (explPane.isVisible()) {
113: sp.setDividerLocation(dl);
114: }
115: }
116: });
117: viewDoc.setSelected(MainEditorFrame.instance.globalProperties
118: .getBoolean("ViewJavaDocInCompletion", true));
119: explPane.setVisible(viewDoc.isSelected());
120:
121: explPane.addTab("JavaDoc", new JScrollPane(javaDocPane));
122: explPane.addTab("Member explorer", new JScrollPane(
123: memberExplorerPane));
124: explPane.setSelectedIndex(0);
125: sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tablePanel,
126: explPane);
127:
128: javaDocPane.setEditable(false);
129: memberExplorerPane.setEditable(false);
130:
131: add(sp, BorderLayout.CENTER);
132:
133: MainEditorFrame.instance.globalProperties
134: .setComponentSizeFromINIFile(this ,
135: "ArgumentsCompletionDialog", fontSize * 50,
136: fontSize * 45, x, y);
137: this .setLocation(x, y);
138: sp.setDividerLocation(MainEditorFrame.instance.globalProperties
139: .getInteger("ArgumentsCompletionDialog_divloc",
140: fontSize * 30));
141: sp.setOneTouchExpandable(true);
142:
143: CompletionUtils.controlTableWithFieldKeys(asp.getTextField(),
144: table, this , ")");
145:
146: table.addKeyListener(new KeyAdapter() {
147: @Override
148: public void keyTyped(KeyEvent ke) {
149: char c = ke.getKeyChar();
150: if (Character.isLetterOrDigit(c)) // important: avoid enter and control keys
151: {
152: asp.getTextField().setText(
153: asp.getTextField().getText() + c);
154: asp.doSearch();
155: }
156: }
157: });
158:
159: ((JComponent) getContentPane()).registerKeyboardAction(
160: new ActionListener() {
161: public void actionPerformed(ActionEvent ae) {
162: wasCancelled = true;
163: setVisible(false);
164: return;
165: }
166: }, "Escape", Accelerators.escape,
167: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
168:
169: ((JComponent) getContentPane()).registerKeyboardAction(
170: new ActionListener() {
171: public void actionPerformed(ActionEvent ae) {
172: wasCancelled = false;
173: setVisible(false);
174: return;
175: }
176: }, "Enter", KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
177: 0, true), // false => not working, let the table "jump"
178: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
179:
180: this .addWindowListener(new WindowAdapter() {
181: @Override
182: public void windowClosed(WindowEvent e) {
183: // not called on cancel
184: saveSettingsOnClose();
185: }
186:
187: @Override
188: public void windowClosing(WindowEvent e) {
189: // not called on cancel
190: saveSettingsOnClose();
191: }
192: /*@Override
193: public void windowDeactivated(WindowEvent e)
194: {
195: saveSettingsOnClose();
196: } */
197: });
198:
199: /*old
200: javaDocPane.addHyperlinkListener(hyperlinkListener = new HyperlinkListener()
201: {
202: public void hyperlinkUpdate(HyperlinkEvent e) {
203: if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
204: JEditorPane pane = (JEditorPane) e.getSource();
205: if (e instanceof HTMLFrameHyperlinkEvent) {
206: HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e;
207: HTMLDocument doc = (HTMLDocument)pane.getDocument();
208: doc.processHTMLFrameHyperlinkEvent(evt);
209: } else {
210: try {
211: //TODO: resolve relative names !
212: System.out.println("URL: "+e.getURL());
213: pane.setPage(e.getURL());
214: } catch (Throwable t) {
215: t.printStackTrace();
216: }
217: }
218: }
219: }
220: });*/
221:
222: javaDocPane
223: .addHyperlinkListener(hyperlinkListener = new HyperlinkListener() {
224: public void hyperlinkUpdate(HyperlinkEvent e) {
225: if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
226: JEditorPane pane = (JEditorPane) e
227: .getSource();
228: if (e instanceof HTMLFrameHyperlinkEvent) {
229: // never occurs ??
230: HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e;
231: HTMLDocument doc = (HTMLDocument) pane
232: .getDocument();
233: doc.processHTMLFrameHyperlinkEvent(evt);
234: } else {
235: try { // oct2007
236: if (e.getURL() != null) {
237: pane.setPage(e.getURL());
238: return;
239: }
240:
241: String relink = e.getDescription();
242: System.out.println("arg relink="
243: + relink);
244:
245: if (actualDisplayedItem == null) {
246: System.out
247: .println("no actualDisplayedItem");
248: } else if (actualDisplayedItem.jdoc == null) {
249: System.out.println("no jdoc");
250: }
251:
252: if (relink != null
253: && actualDisplayedItem != null) {
254: if (actualDisplayedItem.jdoc != null
255: && actualDisplayedItem.jdoc != JDocRes.notFound) {
256: if (browserLastBase == null) {
257: browserLastBase = actualDisplayedItem.jdoc.f;
258: }
259:
260: String tag = null;
261: String query = null; // TODO: handle
262: int pos = relink
263: .indexOf('#');
264: File nf = null;
265: if (pos >= 0) {
266: tag = relink
267: .substring(pos + 1);
268: relink = relink
269: .substring(0,
270: pos);
271: }
272:
273: pos = relink.indexOf('?'); // maybe in the tag ??
274: if (pos >= 0) {
275: query = relink
276: .substring(pos + 1);
277: relink = relink
278: .substring(0,
279: pos);
280: }
281:
282: if (relink.length() == 0) {
283: nf = browserLastBase; // pure tag
284: } else {
285: nf = new File(
286: browserLastBase
287: .getParentFile(),
288: relink);
289: nf = nf
290: .getCanonicalFile();
291: }
292:
293: if (!nf.exists()) {
294: // TODO: try from all known doc roots...
295:
296: pane
297: .setText("<html>Not Found:"
298: + "<br> relink="
299: + relink
300: + "<br> tag="
301: + tag
302: + "<br> file="
303: + nf
304: + "<br> base="
305: + browserLastBase
306: + "<br> first base="
307: + actualDisplayedItem.jdoc.f);
308: return;
309: }
310:
311: browserLastBase = nf;
312:
313: String cont = JavaDocParser
314: .getHTMLContent(nf);
315: if (cont != null) {
316: cont = JavaDocParser
317: .replaceImages(cont);
318: if (tag != null) {
319: pos = cont
320: .indexOf("<A NAME=\""
321: + tag
322: + "\"");
323: if (pos > 0) {
324: cont = cont
325: .substring(pos);
326: }
327: }
328: pane.setText(cont);
329: pane
330: .setCaretPosition(0);
331: } else {
332: System.out
333: .println("NF:"
334: + browserLastBase);
335: }
336: }
337:
338: }
339:
340: } catch (Throwable t) {
341: t.printStackTrace();
342: }
343: }
344: }
345: }
346: });
347:
348: completionManager.editor.getTextPane().addCaretListener(
349: caretListener = new CaretListener() {
350: public void caretUpdate(CaretEvent ce) {
351: if (ce.getDot() <= docOffset) {
352: cancelDialog();
353: }
354:
355: if (!isVisible()) {
356: System.out
357: .println("Called, but not visible !");
358: return;
359: }
360:
361: try {
362: String argText = completionManager.editor
363: .getDocument().getText(docOffset,
364: ce.getDot() - docOffset);
365:
366: int nOpen = StringUtils.count(argText, '(');
367: int nClose = StringUtils
368: .count(argText, ')');
369:
370: if (nClose >= nOpen) {
371: cancelDialog();
372: }
373:
374: //int nargs = StringUtils.count(argText, ","); // todo: ignore recursions (a,b, call(3,3), d): d is the third !
375: int nargs = SyntaxUtils
376: .getArgumentNumberAtEnd(argText);
377: setCurrentArgumentAtDot(nargs);
378: } catch (Exception e) {
379: e.printStackTrace();
380: }
381:
382: }
383: });
384:
385: table.getSelectionModel().addListSelectionListener(
386: new ListSelectionListener() {
387: public void valueChanged(ListSelectionEvent lse) {
388: javaDocPane.setContentType("text/html");
389: int ind = stm
390: .getIndexInUnsortedFromTablePos(table
391: .getSelectedRow());
392: if (ind >= 0) {
393: //String pn = cm.getPackageOrTypeAt(ind);
394: AttrCompletionItem ai = cm
395: .getCompletionItem(ind);
396: updateMemberAndJavaDocView(ai);
397: }
398: }
399: });
400:
401: setVisible(true); // NOT MODAL !!!
402: }
403:
404: private void saveSettingsOnClose() {
405: MainEditorFrame.instance.globalProperties
406: .saveComponentSizeInINIFile(this ,
407: "ArgumentsCompletionDialog");
408: if (explPane.isVisible()) {
409: MainEditorFrame.instance.globalProperties.setInteger(
410: "ArgumentsCompletionDialog_divloc", sp
411: .getDividerLocation());
412: }
413: this .completionManager.editor.getTextPane()
414: .removeCaretListener(caretListener);
415: this .completionManager.openedDialogs.remove(this );
416: javaDocPane.removeHyperlinkListener(hyperlinkListener);
417: actualDisplayedItem = null;
418: clear();
419: }
420:
421: public void selectAndQuit() {
422: this .wasCancelled = false;
423: wasClosed = true;
424: setVisible(false);
425: saveSettingsOnClose(); // must be called, cause setVisible() does not call window listener
426: }
427:
428: public void cancelDialog() {
429: this .wasCancelled = true;
430: wasClosed = true;
431: setVisible(false);
432: saveSettingsOnClose(); // must be called, cause setVisible() does not call window listener
433: }
434:
435: /*bad public boolean getWasCancelled()
436: {
437: return wasCancelled;
438: }*/
439:
440: /** No sense here, the arguments completion just helps the user with comments and argument position.
441: */
442: public String getSelection() {
443: return "NO NO NO NO";
444: }
445:
446: /** Call this delayed after the dialog appears ! */
447: public void setCompletionItems(List<AttrCompletionItem> av) {
448: cm.initialize(av, viewInherited.isSelected(), viewDeprecated
449: .isSelected(), viewOnlyPublic.isSelected());
450:
451: EventQueue.invokeLater(new Runnable() {
452: public void run() {
453: if (table.getRowCount() > 0) {
454: table.getSelectionModel()
455: .setSelectionInterval(0, 0);
456: }
457: }
458: });
459:
460: Thread t = new Thread() {
461: public void run() {
462: addParameterNames();
463: }
464: };
465: t.setPriority(Thread.MIN_PRIORITY);
466: t.start();
467:
468: }
469:
470: /** Adds lazyly, after cm.initialize
471: */
472: private void addParameterNames() {
473: // important...
474: DecompileManager.getInstance().removeDecompForSources();
475:
476: for (AttrCompletionItem aci : new ArrayList<AttrCompletionItem>(
477: cm.allItems)) // DECOUPLE !
478: {
479: if (wasClosed) // wascancelled is NOT ok.
480: {
481: MainEditorFrame.debugOut("add params abort");
482: return;
483: }
484:
485: if (aci.getMember() != null) // of course... getHasArgs is not for here...
486: {
487: if (aci.getMember() instanceof Method
488: || aci.getMember() instanceof Constructor) {
489: List<String> pn = AttributesParamNamesManager
490: .getInstance().getParameterNames(
491: (Member) aci.getMember());
492: if (pn == null) {
493: if (aci.isPublic()) {
494: MainEditorFrame
495: .debugOut("No param names for "
496: + aci.getMember());
497: }
498: // do nothing...
499: } else {
500: String args = AttributesParamNamesManager
501: .createArgumentListWithNames(
502: (Member) aci.getMember(), pn,
503: aci.mapper, false);
504: aci.setNameAndParams(args.substring(1, args
505: .length() - 1));
506: }
507:
508: }
509: }
510:
511: cm.refresh();
512: }
513: //keep sel?
514: cm.refresh();
515: }
516:
517: public void clear() {
518: stm.removeOldListeners();
519: table.setModel(new DefaultTableModel());
520: cm.clear();
521: }
522:
523: int currentArgumentPosition = -1;
524:
525: /** highlight the current argument at dot (bold)
526: */
527: private void setCurrentArgumentAtDot(int count) {
528: if (currentArgumentPosition == count)
529: return;
530: currentArgumentPosition = count;
531: cm.setCurrentArgumentAtDot(count);
532: }
533:
534: private void updateMemberAndJavaDocView(
535: final AttrCompletionItem item) {
536: if (!viewDoc.isSelected())
537: return;
538:
539: if (actualDisplayedItem == item)
540: return;
541: actualDisplayedItem = item;
542: StringBuilder sb = new StringBuilder();
543:
544: if (item.getMember() != null) {
545: String normalStr = "" + item.getMember();
546: sb.append("<br><b><code>"
547: + HTMLUtils.convertCharsToHTML(normalStr)
548: + "</code></b>");
549:
550: // there is no direct general way to call toGenericString() for a member, so we must switch:
551: String genericStr = "";
552: Type[] exceptions = new Type[0];
553: if (item.getMember() instanceof Method) {
554: Method met = (Method) item.getMember();
555: genericStr = met.toGenericString();
556: exceptions = met.getGenericExceptionTypes();
557: } else if (item.getMember() instanceof Field) {
558: genericStr = ((Field) item.getMember())
559: .toGenericString();
560: } else if (item.getMember() instanceof Constructor) {
561: Constructor con = (Constructor) item.getMember();
562: genericStr = con.toGenericString();
563: exceptions = con.getGenericExceptionTypes();
564: }
565:
566: if (genericStr.length() > 0
567: && !genericStr.equals(normalStr)) {
568: sb.append("<br><b><code>Gen: "
569: + HTMLUtils.convertCharsToHTML(genericStr)
570: + "</code></b>");
571: }
572:
573: if (exceptions.length > 0) {
574: sb.append("<br><b><code>Exceptions: "
575: + Arrays.toString(exceptions) + "</code></b>");
576: }
577:
578: if (item.getMember() instanceof Member) {
579: if (((Member) item.getMember()).isSynthetic()) {
580: sb
581: .append("<br><b><code>This member is synthetic, it was introduced by the compiler.</code></b>");
582: }
583: }
584: } else {
585: sb.append("<br><b><code>"
586: + HTMLUtils.convertCharsToHTML(item.getReturnType()
587: + " " + item.getNameAndParams())
588: + "</code></b>");
589: }
590: sb.append("<p>Declaring class = "
591: + HTMLUtils
592: .convertCharsToHTML("" + item.declaringClass));
593: memberExplorerPane.setContentType("text/html");
594: memberExplorerPane.setText("<html><body>" + sb.toString()
595: + "</body></html>");
596: memberExplorerPane.setCaretPosition(0);
597:
598: if (item.getMember() != null) {
599:
600: JDocRes jd = MainEditorFrame.instance.getActualProject()
601: .getJavaDocManager().getJavaDocFor(item);
602: item.jdoc = jd;
603: if (jd != null) {
604: javaDocPane.setText(jd.part);
605: browserLastBase = jd.f;
606: } else {
607: javaDocPane.setText("<html>No Javadoc found");
608: browserLastBase = null;
609: }
610: javaDocPane.setCaretPosition(0);
611: }
612: }
613:
614: static class CompletionModel extends FineGrainTableModel {
615: List<AttrCompletionItem> allItems = new ArrayList<AttrCompletionItem>();
616: List<AttrCompletionItem> filteredItems = new ArrayList<AttrCompletionItem>();
617:
618: /** called later
619: */
620: public void initialize(List<AttrCompletionItem> av,
621: boolean includeInherited, boolean includeDeprecated,
622: boolean onlyPublic) {
623: allItems.addAll(av);
624: filter(includeInherited, includeDeprecated, onlyPublic);
625: }
626:
627: public void clear() {
628: /* may collide with the names resolver thread...
629: for(AttrCompletionItem it : allItems)
630: {
631: it.freeMem();
632: }*/
633: allItems.clear();
634: filteredItems.clear();
635: }
636:
637: public void filter(boolean includeInherited,
638: boolean includeDeprecated, boolean onlyPublic) {
639: synchronized (filteredItems) {
640: filteredItems.clear();
641: filteredItems.addAll(allItems);
642: if (!includeInherited || !includeDeprecated
643: || onlyPublic) // only look in case of limitation
644: {
645: for (int i = filteredItems.size() - 1; i >= 0; i--) // reverse
646: {
647: AttrCompletionItem fi = filteredItems.get(i);
648: if ((fi.isInherited() && !includeInherited)
649: || (fi.deprecated && !includeDeprecated)
650: || (onlyPublic && !fi.isPublic())) {
651: filteredItems.remove(i);
652: }
653: }
654: }
655: }
656:
657: refresh();
658: }
659:
660: private void refresh() {
661: EventQueue.invokeLater(new Runnable() {
662: public void run() {
663: fireTableModelWillChange();
664: fireTableDataChanged();
665: fireTableModelHasChanged();
666: }
667: });
668:
669: }
670:
671: int argumentAtDot = -1;
672:
673: /** -1: no argument selected, 0: first. MUST BE CALLED IN EDT
674: */
675: public void setCurrentArgumentAtDot(int n) {
676: argumentAtDot = n;
677: fireTableModelWillChange();
678: fireTableDataChanged();
679: fireTableModelHasChanged();
680: }
681:
682: /** Creates an html representation with bolded out argument corresponding to the
683: * one set by setCurrentArgumentAtDot(n)
684: */
685: private String highlightCurrentArgAtDot(String argText_,
686: boolean deprecated) {
687: String argText = HTMLUtils.convertCharsToHTML(argText_);
688: StringBuilder sb = new StringBuilder("<html><body>");
689: if (deprecated) {
690: sb.append("<I><b>DEPRECATED</b></I> ");
691: }
692:
693: if (argumentAtDot == -1) {
694: sb.append(argText);
695: return sb.toString();
696: }
697:
698: int c = 0;
699: boolean in = false;
700:
701: int parenthesisCount = 0;
702:
703: if (argumentAtDot == 0) {
704: in = true;
705: sb.append("<b>");
706: }
707:
708: cl: for (int i = 0; i < argText.length(); i++) {
709: char ci = argText.charAt(i);
710: if (ci == '(')
711: parenthesisCount++;
712: if (ci == ')')
713: parenthesisCount--;
714:
715: if (ci == ',' && parenthesisCount == 0) {
716: c++;
717: if (in) {
718: sb.append("</b>,");
719: continue cl;
720: } else if (c == argumentAtDot) {
721: sb.append(",<b>");
722: in = true;
723: continue cl;
724: }
725: }
726: sb.append(ci);
727: }
728:
729: return sb.toString();
730: }
731:
732: public AttrCompletionItem getCompletionItem(int row) {
733: synchronized (filteredItems) {
734: if (row < 0 || row >= filteredItems.size())
735: return null;
736: return filteredItems.get(row);
737: }
738: }
739:
740: public Object getValueAt(int row, int col) {
741: synchronized (filteredItems) {
742: if (row < 0 || row >= filteredItems.size())
743: return ""; //"bad row "+row;
744: if (col == 0)
745: return filteredItems.get(row).kindAndModifiers;
746: if (col == 1)
747: return highlightCurrentArgAtDot(filteredItems.get(
748: row).getNameAndParams(), filteredItems
749: .get(row).deprecated);
750: if (col == 2)
751: return "";
752: if (col == 3)
753: return "";
754: }
755: return "??";
756: }
757:
758: public String getCompletion(int row) {
759: synchronized (filteredItems) {
760: if (row < 0 || row >= filteredItems.size())
761: return "bad row " + row;
762: return filteredItems.get(row).getCompletion();
763: }
764: }
765:
766: public int getRowCount() {
767: return filteredItems.size();
768: }
769:
770: public int getColumnCount() {
771: return 2;
772: }
773:
774: @Override
775: public int getPreferredColumnWidth(int column) {
776: if (column == 0)
777: return 9;
778: if (column == 1)
779: return 50;
780: if (column == 2)
781: return 5;
782: return 5;
783: }
784:
785: @Override
786: public int getColumnAlignment(int column) {
787: return JLabel.LEFT;
788: }
789:
790: @Override
791: public String getColumnName(int c) {
792: if (c == 0)
793: return "mod";
794: if (c == 1)
795: return "arguments";
796: if (c == 2)
797: return "generic";
798: if (c == 3)
799: return "throws";
800: return "??";
801: }
802: }
803:
804: }
|