# SWT AutoComplete



## Chriss_07 (20. Sep 2010)

Hi, ich habe mich mal mit AutoComplete von JFace beschäftigt 
Nun würde ich gerne den String von einer SQL Query füllen lassen, scheitere aber kläglich.
Die AutoComplete Klassen habe ich eingebunden

```
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.swt.widgets.Control;
 
public class MyAutoCompleteField {
   private ContentProposalProvider contentProposalProvider;
   private ContentProposalAdapter  contentProposalAdapter;
 
   public MyAutoCompleteField(final Control control,
                              final IControlContentAdapter controlContentAdapter,
                              final String[] literals,
                              final String[] labels) {
      contentProposalProvider = new ContentProposalProvider(literals, labels);
      contentProposalProvider.setFiltering(false);
      contentProposalAdapter = new ContentProposalAdapter(control, controlContentAdapter, contentProposalProvider, null, null);
      contentProposalAdapter.setPropagateKeys(true);
      contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
   }
 
   public void setProposals(final String[] proposals) {
      contentProposalProvider.setProposals(proposals);
   }
 
   public ContentProposalProvider getContentProposalProvider() {
      return contentProposalProvider;
   }
 
   public ContentProposalAdapter getContentProposalAdapter() {
      return contentProposalAdapter;
   }
}
```


```
import java.util.ArrayList;
 
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
 
public class ContentProposalProvider implements IContentProposalProvider {
   private String[]        proposals;
   private String[]        labels;
   private IContentProposal[]    contentProposals;
   private boolean        filterProposals    = false;
 
   public ContentProposalProvider(String[] proposals, String[] labels) {
      super();
      this.proposals = proposals;
      this.labels = labels;
   }
 
   public IContentProposal[] getProposals(String contents, int position) {
      if (filterProposals) {
         ArrayList list = new ArrayList();
         for (int i = 0; i < proposals.length; i++) {
            if (proposals[i].length() >= contents.length() 
                && proposals[i].substring(0, contents.length()).equalsIgnoreCase(contents)) {
               list.add(makeContentProposal(proposals[i], labels[i]));
            }
         }
         return (IContentProposal[]) list.toArray(new IContentProposal[list.size()]);
      }
      if (contentProposals == null) {
         contentProposals = new IContentProposal[proposals.length];
         for (int i = 0; i < proposals.length; i++) {
            contentProposals[i] = makeContentProposal(proposals[i], labels[i]);
         }
      }
      return contentProposals;
   }
 
   public void setProposals(String[] items) {
      this.proposals = items;
      contentProposals = null;
   }
 
   public void setFiltering(boolean filterProposals) {
      this.filterProposals = filterProposals;
      contentProposals = null;
   }
 
   private IContentProposal makeContentProposal(final String proposal, final String label) {
      return new IContentProposal() {
 
         public String getContent() {
            return proposal;
         }
 
         public String getDescription() {
            // Wenn hier was zurückgegeben wird, dann erscheint dieser Text in einem seperatem Fenster
            return null;  
         }
 
         public String getLabel() {
            return proposal + " - " + label;
         }
 
         public int getCursorPosition() {
            return proposal.length();
         }
      };
   }
}
```


```
Text textField = new Text();
String[] str = {"Ananas", "Apfel", "Banane", "Birne", "Kiwi", "Pflaume" };
String[] str = {"besonders lecker", "schön grün", "wunderbar gebogen", 
                "irgendwie nicht rund", "exotisch", "hmm" };
new MyAutoCompleteField(textField, new TextContentAdapter(), str);
```
Aber ich bekomme mein 
	
	
	
	





```
SELECT fruechte FROM baum GROUP BY Fruechte;
```
nicht in eine String übergeben. Hat wer einen tipp, ich steh heut voll auf dem Schlauch.


----------



## Gast2 (20. Sep 2010)

he was willst du machen???
Einfach das ResultSet oder was du auch immer zurück bekommst auswerten und in einer String Liste zurück geben lassen...


----------



## Chriss_07 (20. Sep 2010)

Ja aber wie mache ich asu dem RS eine String Liste?


----------



## Gast2 (20. Sep 2010)

Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 23.6 Datenbankabfragen


----------



## Chriss_07 (24. Sep 2010)

Danke die Abfrage klappt.
Nun soll eine Auswahl aus der Liste eine zusätzliche ComboBox füllen.
Bestätige ich die Auswahl mit ENTER, dann wird die ComboBox gefüllt, tätige ich die Auswahl mit der Mouse ( doubleClick), dann wird die entsprechende Methode nicht gestartet und die CB nicht gefüllt, bzw eine vorherige Auswahl steht dann noch drinne.

```
Text textField = new Text();
Obstbaum ob = new Obstbaum();
	String[] str =  ob.getFruechte();
new MyAutoCompleteField(textField, new TextContentAdapter(), str);
textField.addKeyListener(new org.eclipse.swt.events.KeyAdapter() {
            public void keyPressed(org.eclipse.swt.events.KeyEvent e) {
                if ((e.keyCode == SWT.CR)||(e.keyCode == SWT.KEYPAD_CR)) {
                    pressEnter();
                }
            }
        });
textField.addMouseListener(new org.eclipse.swt.events.MouseListener(){
            public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e){
                if((e.button == SWT.MouseDoubleClick)){
                pressEnter();
            }
```
Der DoubleClick in der Liste löst die Methode nicht aus, Enter schon. Wenn ich doppelt in das textField klicke, dann wird die Methode gestartet. 
Wie setzte ich den MouseListener richtig ein?


----------



## Gast2 (24. Sep 2010)

Debugen!!! Mach ein breakpoint die doppelklick methode ob du da überhaupt reinkommst...


----------



## Chriss_07 (24. Sep 2010)

Ich komme da nur rein, wenn ich den Doppelklick im textfeld ausführe. Innerhalb der PopupListe aus dem AutoComplete funktioniert nur die Entertaste.


----------



## Gast2 (24. Sep 2010)

Du hast ja auch nur einen Listener auf das Textfeld und nicht auf das Popup...


----------



## Chriss_07 (25. Sep 2010)

Beim KeyListener funktioniert es ja auch. ich habe das AutoComplete als import mittels 
	
	
	
	





```
org.eclipse.jface.fieldassist.AutoCompleteField
```
 eingebunden.


----------



## Gast2 (25. Sep 2010)

Chriss_07 hat gesagt.:


> Beim KeyListener funktioniert es ja auch. ich habe das AutoComplete als import mittels
> 
> 
> 
> ...



Weil das Complete field die KeyEvents weiterleitet mit den MouseEvents eben nicht...

```
contentProposalAdapter.setPropagateKeys(true);
```


----------



## Chriss_07 (26. Sep 2010)

```
public void keyPressed(org.eclipse.swt.events.KeyEvent e) {
                if ((e.keyCode == SWT.CR)||(e.keyCode == SWT.KEYPAD_CR) || (e.keyCode == SWT.MouseDoubleClick)) {
```
Geht auch nicht. Kann man den MouseListener nicht mit einbinden?


----------



## Gast2 (26. Sep 2010)

deine if abfrage macht auch keinen sinn...


----------



## Chriss_07 (21. Okt 2010)

Hi SirWayne,
ich habe die letzte Zeit an anderen Baustellen gearbeitet aber vlt. können wir noch einmal auf den Mouse Button im ContentProposalAdapter eingehen, denn das Problem besteht immer noch und lässt mir keine Ruhe. 
Also so wie ich das sehe übergibt die Klasse ContentPRoposalAdapter das Objekt nur für Keyboardtasten ContentProposalAdapter . Hast du einen Rat für mich?
Gruß C


----------



## Gast2 (21. Okt 2010)

Wie schon gesagt WO willst du den Doubleclick abfangen? Wenn im Textfeld Listener auf Textfielf wenn im Popup Listener auf das das Popup

Ein gesamtes KSKB würde auch vielleicht weiterhelfen...


----------



## Chriss_07 (21. Okt 2010)

Hier mein kurzes Beispiel. Also in der PopupListe kann ein Objekt auch mittels Mouse gewählt werden, finde ich inhaltlich korrekt. Ob das Objekt selbst dann am Textfeld oder mittels Mouse Click im Popup übergeben wird, ist mir der geringere Code Aufwand lieber 
	
	
	
	





```
String textfeld = text.getText();
String mix = ob.getObstsalat(textfeld);
```


```
package test;

import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

public class Obstsalat {
    
    private static Text text = null;
    private static Combo combo = null;
    
    
    public static void main (String [] args) {
        
        Display display = new Display ();
        Shell shell = new Shell (display);
        shell.setLayout (new RowLayout ());
        
        text = new Text(shell, SWT.SINGLE | SWT.BORDER);
        final Obstbaum ob = new Obstbaum();
        String[] str =  ob.getFruechte();
        new MyAutoCompleteField(text, new TextContentAdapter(), str);
        text.setTextLimit(8);
        text.setEditable(true);
        text.addKeyListener(new org.eclipse.swt.events.KeyAdapter() {
            public void keyPressed(org.eclipse.swt.events.KeyEvent e) {
                if ((e.keyCode == SWT.CR)||(e.keyCode == SWT.KEYPAD_CR)) {
                        String textfeld = text.getText();
                        String mix = ob.getObstsalat(textfeld);
                        combo.setText(mix);
                }
            }
        });
                
        combo = new Combo (shell, SWT.NONE);


        shell.pack ();
        shell.open ();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }
        display.dispose ();
    }
    }
```


```
package test;

public class Obstbaum {
    
    public String[] getFruechte(){
        String[] fr = {"Ananas", "Apfel", "Banane", "Birne", "Kiwi", "Pflaume" };
        return fr;

        }

    public String getObstsalat(String textfeld) {
        if( textfeld == "Ananas"){
            String result = "besonders lecker";
            return result;
        }
        if( textfeld == "Apfel"){
            String result = "schön grün";
            return result;
        }
        if( textfeld == "Banane"){
            String result = "wunderbar gebogen";
            return result;
        }
        if( textfeld == "Birne"){
            String result = "irgendwie nicht rund";
            return result;
        }
        if( textfeld == "Kiwi"){
            String result = "exotisch";
            return result;
        }
        if( textfeld == "Pflaume"){
            String result = "hmm";
            return result;
        }else
        return textfeld;
}
}
```


----------



## js_rcp (20. Dez 2010)

Hi,

wie lässt sich HTML als Beschreibung verwenden. Ich wundere mich, das ich hierzu nichts finden kann, da es doch ein Jeder aus der Eclipse code completion kennt.

Viele Grüße
js


----------



## Gast2 (20. Dez 2010)

Also eine Beschreibung und eine Autocompletion sind für mich zweierlei...
Und die Autocompletion sieht nicht nach HTML aus...


----------



## Sonecc (20. Dez 2010)

Ich würde ma vermuten, dass er Javadoc meint... ka


----------



## Wildcard (20. Dez 2010)

Das Info Popup kommt wenn dein Proposal ICompletionProposalExtension5 implementiert:
ICompletionProposalExtension5 (Eclipse Platform API Specification)

Wenn du die Hilfe als HTML Rendern willst, musst du ICompletionProposalExtension3 implementieren und dort  einen passenden IInformationControlCreator instanzieren. Es gibt eine Default Implementierung die HTML Rendered, aber mir ist gerade der Klassenname entfallen


----------



## js_rcp (21. Dez 2010)

Hi,

Meine Frage bezog sich auf die IContentProposalProvider Schnittstelle, da ich den ContentProposalAdapter verwende und bei Text Kontrollern aus verschiedenen Views anmelde. Mir fehlt "nur" eine Darstellung der description als HTML. 

ICompletionProposal hatte ich gar nicht auf dem Radar. Mir ist auch nicht klar wie ich die den ContentAssistant verwenden kann, wenn ich nur swt Text widgets zur Verfügung habe.

In einem anderen Forum war ich nicht weitergekommen (zur Dokumentation):
[news.eclipse.platform] Content Proposal description with HTML render 

Viele Grüße und schonmal vielen Dank!
js


----------



## Wildcard (21. Dez 2010)

> Meine Frage bezog sich auf die IContentProposalProvider Schnittstelle, da ich den ContentProposalAdapter verwende und bei Text Kontrollern aus verschiedenen Views anmelde. Mir fehlt "nur" eine Darstellung der description als HTML.


IContentProposalProvider leifert IContentProposal. Du musst eine eigene implementierung eines IContentProposal bereitstellen  (du kannst natürlich subclassen) die zustätzlich ICompletionProposalExtension5  und ICompletionProposalExtension3 implementiert. Dann solltest du auch HTML als Description rendern können


----------



## Gast2 (22. Dez 2010)

Ich versuch grad das ganze mal mit einem Textfeld nachzuvollziehen von was ihr redet.
Kann das sein, dass man dann ein eigenes AutoCompleteField benötigt mit einem eigenen IContentProposalProvider der in der getProposals Methode die eignen IContentProposal zurückliefert? 
Man benötigt also 3 eigene Klassen?


----------



## Wildcard (22. Dez 2010)

Ein eigenes Textfeld braucht man eigentlich nicht.


----------



## Gast2 (22. Dez 2010)

Wildcard hat gesagt.:


> Ein eigenes Textfeld braucht man eigentlich nicht.



Hab ich auch nicht gesagt?

Also ich kenne es bisher so

```
new org.eclipse.jface.fieldassist.AutoCompleteField(control, new TextContentAdapter(), proposals)
```

aber da kann man schon mal *keine *Description und label mitgeben..

Also braucht man eine neue Klasse für AutoCompleteField mit einem eigenen ContentProposalProvider da der SimpleContentProposalProvider auch keien Description verwendet.

Also sowas hier z.B. damit kann schon mal die Beschreibung sich anzeigen lassen

```
public class ContentProposalProvider implements IContentProposalProvider {
	     private String[]		proposals;
	     private String[]		description;
	     private IContentProposal[]	contentProposals;
	     private boolean		filterProposals	= false;
	   
	     public ContentProposalProvider(String[] proposals, String[] description) {
	        super();
	        this.proposals = proposals;
	        this.labels = labels;
	     }
	   
	     public IContentProposal[] getProposals(String contents, int position) {
	        if (filterProposals) {
	           List<IContentProposal> list = new ArrayList<IContentProposal>();
	           for (int i = 0; i < proposals.length; i++) {
	              if (proposals[i].length() >= contents.length() 
	                  && proposals[i].substring(0, contents.length()).equalsIgnoreCase(contents)) {
	                 list.add(new ContentProposal(proposals[i], labels[i]));
	              }
	           }
	           return (IContentProposal[]) list.toArray(new IContentProposal[list.size()]);
	        }
	        if (contentProposals == null) {
	           contentProposals = new IContentProposal[proposals.length];
	           for (int i = 0; i < proposals.length; i++) {
	              contentProposals[i] = new ContentProposal(proposals[i], labels[i]);
	           }
	        }
	        return contentProposals;
	     }
	   
	     public void setFiltering(boolean filterProposals) {
	        this.filterProposals = filterProposals;
	        contentProposals = null;
	     }
	  }
	  
	  public class MyAutoCompleteField {
		   private ContentProposalProvider contentProposalProvider;
		   private ContentProposalAdapter  contentProposalAdapter;
		 
		   public MyAutoCompleteField(final Control control,
		                              final IControlContentAdapter controlContentAdapter,
		                              final String[] literals,
		                              final String[] description) {
		      contentProposalProvider = new ContentProposalProvider(literals, description);
		      contentProposalProvider.setFiltering(true);
		      contentProposalAdapter = new ContentProposalAdapter(control, controlContentAdapter, contentProposalProvider,null, null);
		      contentProposalAdapter.setPropagateKeys(true);
		      contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
		   }
		 
		   public ContentProposalProvider getContentProposalProvider() {
		      return contentProposalProvider;
		   }
		 
		   public ContentProposalAdapter getContentProposalAdapter() {
		      return contentProposalAdapter;
		   }
		}
```

Aber wie das jetzt mit HTML gehen soll da häng ich... Man brauch einen eigenen ContentProposal aber was die Methoden dann zurück liefern und wann die augerufen werden keine ahnung ???:L


```
private class MyContentProposal extends ContentProposal implements ICompletionProposalExtension5 ,ICompletionProposalExtension3 {

		public MyContentProposal(String content) {
			super(content);
		}
		
		

		public MyContentProposal(String content, String label,
				String description, int cursorPosition) {
			super(content, label, description, cursorPosition);
		}



		public MyContentProposal(String content, String label,
				String description) {
			super(content, label, description);
		}



		public MyContentProposal(String content, String description) {
			super(content, description);
		}



		@Override
		public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
			System.out.println(monitor);
			return null;
		}

		@Override
		public IInformationControlCreator getInformationControlCreator() {
			System.out.println("hier");
			return null;
		}

		@Override
		public CharSequence getPrefixCompletionText(IDocument document,
				int completionOffset) {
			System.out.println("hier1");
			return null;
		}

		@Override
		public int getPrefixCompletionStart(IDocument document,
				int completionOffset) {
			System.out.println("hier2");
			return 0;
		}

		  
	  }
```


----------



## Wildcard (22. Dez 2010)

Das AutoCompleteField ist nur eine Utility Klasse, die braucht man also nicht wirklich (hat ja auch nur 10 Zeilen, oder so). Aber es spricht natürlich nichts dagegen sich ein eigenes solches AutoCompleteField zu erstellen.



> Aber wie das jetzt mit HTML gehen soll da häng ich... Man brauch einen eigenen ContentProposal aber was die Methoden dann zurück liefern und wann die augerufen werden keine ahnung


Bei getAdditionalProposalInfo lieferst du einen HTML String zurück.

Bei getInformationControlCreator gibst du einen IInformationControlCreator zurück. Wenn du einfach HTML rendern willst, dann implementiere deinen IInformationControlCreator zB so:


```
class DefaultInformationControlCreator extends AbstractReusableInformationControlCreator {
		public IInformationControl doCreateInformationControl(Shell shell) {
			return new DefaultInformationControl(shell, true);
		}
}
```


----------



## Gast2 (22. Dez 2010)

Mich hat es nur gewundert, dass die Methoden nie augerufen wurden, darum hab ich die System.out reingemacht.
Fehlt dazu ein ExtensionPoint oder sowas?

Also hier die Utility Klasse

```
public class MyAutoCompleteField {
		   private ContentProposalProvider contentProposalProvider;
		   private ContentProposalAdapter  contentProposalAdapter;
		 
		   public MyAutoCompleteField(final Control control,
		                              final IControlContentAdapter controlContentAdapter,
		                              final String[] literals,
		                              final String[] labels) {
		      contentProposalProvider = new ContentProposalProvider(literals, labels);
		      contentProposalProvider.setFiltering(true);
		      contentProposalAdapter = new ContentProposalAdapter(control, controlContentAdapter, contentProposalProvider,null, null);
		      contentProposalAdapter.setPropagateKeys(true);
		      contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
		   }
		 
		   public ContentProposalProvider getContentProposalProvider() {
		      return contentProposalProvider;
		   }
		 
		   public ContentProposalAdapter getContentProposalAdapter() {
		      return contentProposalAdapter;
		   }
		}
```

Der Provoider einfach den Simple Provider angepasst


```
public class ContentProposalProvider implements IContentProposalProvider {
	     private String[]		proposals;
	     private String[]		decription;
	     private IContentProposal[]	contentProposals;
	     private boolean		filterProposals	= false;
	   
	     public ContentProposalProvider(String[] proposals, String[] decription) {
	        super();
	        this.proposals = proposals;
	        this.decription = decription;
	     }
	   
	     public IContentProposal[] getProposals(String contents, int position) {
	        if (filterProposals) {
	           List<IContentProposal> list = new ArrayList<IContentProposal>();
	           for (int i = 0; i < proposals.length; i++) {
	              if (proposals[i].length() >= contents.length() 
	                  && proposals[i].substring(0, contents.length()).equalsIgnoreCase(contents)) {
	                 list.add(new MyContentProposal(proposals[i], decription[i]));
	              }
	           }
	           return (IContentProposal[]) list.toArray(new IContentProposal[list.size()]);
	        }
	        if (contentProposals == null) {
	           contentProposals = new IContentProposal[proposals.length];
	           for (int i = 0; i < proposals.length; i++) {
	              contentProposals[i] = new MyContentProposal(proposals[i], decription[i]);
	           }
	        }
	        return contentProposals;
	     }
	   
	     public void setProposals(String[] items) {
	        this.proposals = items;
	        contentProposals = null;
	     }
	   
	     public void setFiltering(boolean filterProposals) {
	        this.filterProposals = filterProposals;
	        contentProposals = null;
	     }
```

Und dann den eigenen Content Proposal

```
private class MyContentProposal extends ContentProposal implements ICompletionProposalExtension5 ,ICompletionProposalExtension3 {

		public MyContentProposal(String content) {
			super(content);
		}
		
		

		public MyContentProposal(String content, String label,
				String description, int cursorPosition) {
			super(content, label, description, cursorPosition);
		}



		public MyContentProposal(String content, String label,
				String description) {
			super(content, label, description);
		}



		public MyContentProposal(String content, String description) {
			super(content, description);
		}



		@Override
		public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
			return getDescription();
		}

		@Override
		public IInformationControlCreator getInformationControlCreator() {
			System.out.println("hier");
			return new DefaultInformationControlCreator();
		}

		@Override
		public CharSequence getPrefixCompletionText(IDocument document,
				int completionOffset) {
			System.out.println("hier1");
			return null;
		}

		@Override
		public int getPrefixCompletionStart(IDocument document,
				int completionOffset) {
			System.out.println("hier2");
			return 0;
		}

		  
	  }
	  
	  class DefaultInformationControlCreator extends AbstractReusableInformationControlCreator {
	        public IInformationControl doCreateInformationControl(Shell shell) {
	            return new DefaultInformationControl(shell, true);
	        }
	}
```

Aufruf in einer View

```
String[] str = {"Ananas", "Apfel", "Banane", "Birne", "Kiwi", "Pflaume" };
		String[] str2 = {"<br>besonders lecker</br>", "schön grün", "wunderbar gebogen", 
                "irgendwie nicht rund", "exotisch", "hmm" };

		new MyAutoCompleteField(text, new TextContentAdapter(), str, str2);
```


----------



## js_rcp (22. Dez 2010)

Wenn ich das so richtig sehe kann ContentProposalAdapter gar keine Erweiterung der description verarbeiten. Es ist ja nicht mal möglich die default Selektion nach dem Öffnen der Popupbox zu deaktivieren.


Auszug aus der inneren Klasse InfoPopuDialog des ContentProposalAdapter.java


```
IContentProposal p = getSelectedProposal();
								if (p != null) {
									String description = p.getDescription();
									if (description != null) {
										if (infoPopup == null) {
											infoPopup = new InfoPopupDialog(getShell());
											infoPopup.open();
											infoPopup.getShell().addDisposeListener(
													new DisposeListener() {
														public void widgetDisposed(
																DisposeEvent event) {
															infoPopup = null;
														}
													});
										}
										infoPopup.setContents(p.getDescription());

										showInfoPopupHtmlDialog(description);
```

Gibt es eine Alternative Implementierung für ContentProposalAdapter? 

Was ich momentan versuche ist, als aus dem ProposalProvider  getDescription() immer null zurückzuliefern um das InfoPopup zu unterdrücken. Dann erzeuge ich ein BrowserInformationControl Element und übergebe die description, d.h. den HTML Inhalt. Ist nen Workaround, da ich momentan keine andere Möglichkeit sehe, außer komplett IContentAssistant umzusteigen. Code für die Diskussion adde ich später...

Tutorial für IContentAssistant:
Equipping SWT applications with content assistants

VG
js


----------



## Wildcard (22. Dez 2010)

Ach, ich sehe jetzt was das Problem ist. Mir war gar nicht bewusst das es zwei verschiedene Interfaces für Completions gibt, IContentProposal und ICompletionProposal. ICompletionProposal ist das mächtigere mit dem dann auch die Info Popups, styled strings und HTML Rendering möglich sind, das funktioniert aber wohl nur auf einem SourceViewer. Der SourceViewer kann allerdings auch einzeilig sein und wie ein normales Textfeld aussehen.


----------



## Gast2 (23. Dez 2010)

Wildcard hat gesagt.:


> Ach, ich sehe jetzt was das Problem ist. Mir war gar nicht bewusst das es zwei verschiedene Interfaces für Completions gibt, IContentProposal und ICompletionProposal. ICompletionProposal ist das mächtigere mit dem dann auch die Info Popups, styled strings und HTML Rendering möglich sind, das funktioniert aber wohl nur auf einem SourceViewer. Der SourceViewer kann allerdings auch einzeilig sein und wie ein normales Textfeld aussehen.



Okay gut zu wissen.
Aber einen SourceViewer als Textfeld find ich unschön.


----------



## Gast2 (23. Dez 2010)

js_rcp hat gesagt.:


> Wenn ich das so richtig sehe kann ContentProposalAdapter gar keine Erweiterung der description verarbeiten. Es ist ja nicht mal möglich die default Selektion nach dem Öffnen der Popupbox zu deaktivieren.
> 
> 
> Auszug aus der inneren Klasse InfoPopuDialog des ContentProposalAdapter.java
> ...



Mach dir einen eigenen ContentProposalAdapter  überschreib die enstprechende Methode die für das öffnen zuständig ist ich denke mal open und schau dir den Code von dem SourceViewer an und kopier den raus. Vielleicht kennt Wildcard die Stelle wo das Popup mit den Informationen zusammengebaut wird.


----------



## js_rcp (4. Mai 2011)

SirWayne hat gesagt.:


> Mach dir einen eigenen ContentProposalAdapter  überschreib die enstprechende Methode die für das öffnen zuständig ist ich denke mal open und schau dir den Code von dem SourceViewer an und kopier den raus. Vielleicht kennt Wildcard die Stelle wo das Popup mit den Informationen zusammengebaut wird.



Da ich einige Monate nicht an dem Problem gearbeitet zwar spät und nicht schön aber immerhin ein Lösungsweg:

Die Klasse ContentProposalAdapter überschreiben. Die Variable infoPopup anpassen und den InfoDialog überschreiben mit eigener Implementierung. 

```
if (infoPopup == null) { //FIXME: workaround since html is not supported
											infoPopup = new MyInfoPopupDialog(getShell(), 
													((SearchContentProposalImpl)p).getPath()); 
                                                                infoPopup.setContents(p.getDescription());
								infoPopup.open();
											infoPopup.getShell().addDisposeListener(
													new DisposeListener() {
														public void widgetDisposed(
																DisposeEvent event) {
															
															if (!hasFocus()) {//close popup too if focus is lost
																closeProposalPopup();
															}
															infoPopup = null;
															
														}
													});
										}
```


```
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/*
 * Internal class used to implement the secondary popup.
 */

public class MyInfoPopupDialog extends PopupDialog {

	private static final String EMPTY = null;

	/*
	 * The text control that displays the text.
	 */
	// private Text text;

	/*
	 * The String shown in the popup.
	 */
	private String contents = EMPTY;

	private Browser browser;

	/*
	 * Construct an info-popup with the specified parent.
	 */
	public MyInfoPopupDialog(Shell aParent, String aProposalPath) {
		this(aParent, PopupDialog.HOVER_SHELLSTYLE, false, true, true, false, false, aProposalPath,
				" Test Info Text ....");
	}

	public MyInfoPopupDialog(Shell aParent, int aShellStyle, boolean aTakeFocusOnOpen,
			boolean aPersistSize, boolean aPersistLocation, boolean aShowDialogMenu,
			boolean aShowPersistActions, String aTitleText, String aInfoText) {
		super(aParent, aShellStyle, aTakeFocusOnOpen, aPersistSize, aPersistLocation,
				aShowDialogMenu, aShowPersistActions, aTitleText, aInfoText);
	}

	/*
	 * Create a text control for showing the info about a proposal.
	 */

	@Override
	protected Control createDialogArea(Composite parent) {
		browser = new Browser(parent, SWT.NONE);

		// since SWT.NO_FOCUS is only a hint...
		browser.addFocusListener(getFocusListener());
		return browser;
	}

	@Override
	public boolean close() {

		removeFocusGainedListener();
		// close the proposalbox too if it is not selected...
		return super.close();
	}

	private void removeFocusGainedListener() {
		if (!browser.isDisposed()) {
			browser.removeFocusListener(getFocusListener());
		}
	}

	private FocusAdapter itsFocusAdapter;

	public FocusAdapter getFocusListener() {
		if (itsFocusAdapter == null) {
			itsFocusAdapter = new FocusAdapter() {

			};
		}
		return itsFocusAdapter;
	}

	/*
	 * Adjust the bounds so that we appear adjacent to our parent shell
	 */
	@Override
	protected void adjustBounds() {
		Rectangle parentBounds = getParentShell().getBounds();
		Rectangle proposedBounds;
		// Try placing the info popup to the right
		Rectangle rightProposedBounds = new Rectangle(parentBounds.x + parentBounds.width
				+ PopupDialog.POPUP_HORIZONTALSPACING, parentBounds.y
				+ PopupDialog.POPUP_VERTICALSPACING, parentBounds.width, parentBounds.height);
		rightProposedBounds = getConstrainedShellBounds(rightProposedBounds);
		// If it won't fit on the right, try the left
		if (rightProposedBounds.intersects(parentBounds)) {
			Rectangle leftProposedBounds = new Rectangle(parentBounds.x - parentBounds.width
					- POPUP_HORIZONTALSPACING - 1, parentBounds.y, parentBounds.width,
					parentBounds.height);
			leftProposedBounds = getConstrainedShellBounds(leftProposedBounds);
			// If it won't fit on the left, choose the proposed bounds
			// that fits the best
			if (leftProposedBounds.intersects(parentBounds)) {
				if (rightProposedBounds.x - parentBounds.x >= parentBounds.x - leftProposedBounds.x) {
					rightProposedBounds.x = parentBounds.x + parentBounds.width
							+ PopupDialog.POPUP_HORIZONTALSPACING;
					proposedBounds = rightProposedBounds;
				} else {
					leftProposedBounds.width = parentBounds.x - POPUP_HORIZONTALSPACING
							- leftProposedBounds.x;
					proposedBounds = leftProposedBounds;
				}
			} else {
				// use the proposed bounds on the left
				proposedBounds = leftProposedBounds;
			}
		} else {
			// use the proposed bounds on the right
			proposedBounds = rightProposedBounds;
		}
		getShell().setBounds(proposedBounds);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.PopupDialog#getForeground()
	 */
	@Override
	protected Color getForeground() {
		return Display.getDefault().getSystemColor(SWT.COLOR_INFO_FOREGROUND);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.PopupDialog#getBackground()
	 */
	@Override
	protected Color getBackground() {
		return Display.getDefault().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
	}

	/*
	 * Set the text contents of the popup.
	 */
	void setContents(String newContents) {
		if (newContents == null) {
			newContents = EMPTY;
		}
		this.contents = newContents;
		if (browser != null && !browser.isDisposed()) {
			browser.setText(contents);
		}
	}

	/*
	 * Return whether the popup has focus.
	 */
	boolean hasFocus() {
		if (browser == null || browser.isDisposed()) {
			return false;
		}
		return browser.getShell().isFocusControl() || browser.isFocusControl();
	}
}
```


----------

