Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 05/07/2009, à 14:26

haile_selassie

position composants java

Bonjour,
J'aimerais faire un nouveau composant java, héritant du JTextField.
La nouvelle fonctionnalité du composant serait la suivante: quand un utilisateur commence à taper du texte, un popup apparait pour lui présenter des choix en rapport avec ce qu'il a déjà commencé à taper. Typiquement, c'est ce qui arrive sur la page de recherche de google ou dans thunderbird quand on commence à taper une adresse.
Les différents choix possible sont passés au constructeur sous la forme d'une arraylist de String.
Jusque là, ce que j'ai réussi à faire: faire apparaitre le pop up avec les différentes propositions, et quand l'utilisateur choisit une des propositions, le JTextField est complété. Mon seul soucis réside au niveau du placement du pop up. J'aimerais qu'il soit bien évidemment toujours juste au dessous du TextField, mais je n'ai pas trouvé la méthode qui me permette de trouver des coordonnées absolues d'un composant. Donc ça fait que je n'arrive pas à placer le pop up en fonction de la position du Field, de sa hauteur et de sa largeur.

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;

public class JtextFieldLegend extends JTextField {
    ArrayList<String> donnee = new ArrayList<String>();
    boolean afficher = false;
    JPopupMenu popup = new JPopupMenu();
    JButton button = new JButton();

    public JtextFieldLegend(ArrayList<String> entreesPossibles, Dimension d) {
	this.setPreferredSize(d);
	this.setFocusable(true);
	this.addKeyListener(new keyListener(this));
	donnee = entreesPossibles;
    }


    /**
     * Méthode qui s'occupe de la gestion des changements du popup
     * 
     */
    public void popupInvoke() {
	popup = new JPopupMenu();
	StringBuffer sb = new StringBuffer("");

	int pos = -1;
	ArrayList<String> temp = new ArrayList<String>();
	for (int j = 0; j < donnee.size(); j++) {
	    sb = new StringBuffer(donnee.get(j));
	    pos = -1;
	    pos = sb.indexOf(this.getText());
	    if (pos != -1) {
		temp.add(donnee.get(j));
	    }
	}
	if (temp.size() > 0) {

	    if (!this.getText().equals("")) {
		for (int k = 0; k < temp.size(); k++) {
		    JMenuItem item = new JMenuItem(temp.get(k));
		    item.addActionListener(new listener(this));
		    popup.add(item);
		}

		popup.setPreferredSize(new Dimension(this.getWidth() - 1, temp
			.size() * 19));

	    }
	}

    }

    /**
     * Ecouteur du menu popup
     * 
     */
    public class listener implements ActionListener {
	JtextFieldLegend field;
	String s;
	boolean b = false;

	public listener(JtextFieldLegend field) {
	    this.field = field;

	}

	public void actionPerformed(ActionEvent arg0) {
	    if (arg0.getSource().getClass() == JButton.class) {
		s = field.getText();
		for (String str : field.getDonnee()) {
		    if (s.equals(str)) {
			b = true;
			break;
		    }
		}
		if (b == false) {
		    field.getDonnee().add("s");
		}

	    } else
		field.setText(arg0.getActionCommand());
	}
    }

    /**
     * Ecouteur du JtextField
     * 
     */
    class keyListener implements KeyListener {
	JtextFieldLegend field;

	public keyListener(JtextFieldLegend leg) {
	    this.field = leg;
	}

	public void keyPressed(KeyEvent arg0) {

	}

	public void keyReleased(KeyEvent arg0) {
	    field.popupInvoke();
	    field.popup.show(arg0.getComponent(), arg0.getComponent().getX()
		    - field.getWidth() / 2 + 3, arg0.getComponent().getY()
		    + field.getHeight() - 7);
	    field.requestFocus();
	}

	public void keyTyped(KeyEvent arg0) {

	}

    }

    public ArrayList<String> getDonnee() {
	return donnee;
    }

    public void setDonnee(ArrayList<String> donnee) {
	this.donnee = donnee;
    }

    public static void main(String[] arg) {
	ArrayList<String> v = new ArrayList<String>();
	v.add("blabla");
	v.add("tuututut");
	v.add("tutitititi");
	JButton but = new JButton("ok");
	JtextFieldLegend leg = new JtextFieldLegend(v, new Dimension(300, 20));

	JFrame frame = new JFrame();
	frame.setSize(new Dimension(600, 600));
	frame.setLayout(new FlowLayout());
	frame.add(leg);
	frame.setLocationRelativeTo(null);
	frame.setVisible(true);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Le soucis se situe donc au niveau de:
        field.popup.show(arg0.getComponent(), arg0.getComponent().getX()
            - field.getWidth() / 2 + 3, arg0.getComponent().getY()
            + field.getHeight() - 7);

Là, ça marche parce que j'ai trafiqué les coordonnées pour que ça marche, mais si je change la taille du JTextField, ça ne fonctionne plus.
pour info, ça donne ça:

http://omploader.org/vMXhkNg
Et pour info aussi: j'ai testé plein de techniques, sans succès. Des fois, ça marchait quelle que soit la taille du TextField, mais dès que je rajoutais un composant dans la frame, ça ne marchait plus.

Merci à ceux qui pourraient m'aider smile

Hors ligne

#2 Le 07/07/2009, à 11:32

jofab

Re : position composants java

La position en absolue sur l'ecran c'est getLocationOnScreen (dans Component). Dans le composant parent c'est getBounds() (ou getLocation())
regarde aussi getPopupLocation() et getToolTipLocation() dans JComponent
Pour avoir les coordonnees dans la fenetre tu es certainement obligé de faire un getBounds et de boucler sur les parents en faisant le changement de repere à chaque iteration jusqu'à arriver à la fenetre. De mémoire, je ne suis pas certain qu'il y ai une méthode direct pour ca...
Je sais pas si ca repond à ton pb ?
Jofab

Hors ligne