SWT AutoComplete

Chriss_07

Aktives Mitglied
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
Java:
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;
   }
}

Java:
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();
         }
      };
   }
}
Java:
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
SQL:
SELECT fruechte FROM baum GROUP BY Fruechte;
nicht in eine String übergeben. Hat wer einen tipp, ich steh heut voll auf dem Schlauch.
 
G

Gast2

Gast
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

Aktives Mitglied
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.
Java:
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?
 
G

Gast2

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

Chriss_07

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

Chriss_07

Aktives Mitglied
Beim KeyListener funktioniert es ja auch. ich habe das AutoComplete als import mittels
Code:
org.eclipse.jface.fieldassist.AutoCompleteField
eingebunden.
 
G

Gast2

Gast
Beim KeyListener funktioniert es ja auch. ich habe das AutoComplete als import mittels
Code:
org.eclipse.jface.fieldassist.AutoCompleteField
eingebunden.

Weil das Complete field die KeyEvents weiterleitet mit den MouseEvents eben nicht...
Java:
contentProposalAdapter.setPropagateKeys(true);
 

Chriss_07

Aktives Mitglied
Java:
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?
 

Chriss_07

Aktives Mitglied
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
 
G

Gast2

Gast
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...
 
Zuletzt bearbeitet von einem Moderator:

Chriss_07

Aktives Mitglied
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
Java:
String textfeld = text.getText();
String mix = ob.getObstsalat(textfeld);

Java:
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 ();
    }
    }

Java:
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

Mitglied
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
 
G

Gast2

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

js_rcp

Mitglied
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

Top Contributor
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
 
G

Gast2

Gast
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?
 
G

Gast2

Gast
Ein eigenes Textfeld braucht man eigentlich nicht.

Hab ich auch nicht gesagt?

Also ich kenne es bisher so
Java:
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
Java:
  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

Java:
	  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

Top Contributor
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:

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

Gast2

Gast
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
Java:
  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

Java:
	  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
Java:
	  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
Java:
		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);
 
Zuletzt bearbeitet von einem Moderator:

js_rcp

Mitglied
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

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

Top Contributor
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.
 
G

Gast2

Gast
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.
 
G

Gast2

Gast
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

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

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.
 
Zuletzt bearbeitet von einem Moderator:

js_rcp

Mitglied
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.
Java:
				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;
															
														}
													});
										}

Java:
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();
	}
}
 

Ähnliche Java Themen

Neue Themen


Oben