Position absolue d'un composant?

bob22mael Messages postés 4 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 14 juin 2010 - 1 juil. 2009 à 15:32
deglingo592003 Messages postés 77 Date d'inscription jeudi 27 novembre 2008 Statut Membre Dernière intervention 31 janvier 2014 - 2 juil. 2009 à 09:15
Salut.
j'aimerais récupérer la position absolue d'un composant pour pouvoir positionner un second composant en conséquence.
Alors j'ai tenté ça:
 public static void main(String[] arg) {
    JFrame frame = new JFrame();
    frame.setSize(new Dimension(600, 600));
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTextField field = new JTextField();
    field.setPreferredSize(new Dimension(300, 20));
    frame.setLayout(new FlowLayout());
    frame.add(field);
    Point pointFrame = new Point();
    SwingUtilities.convertPointToScreen(pointFrame, frame);
    Point pointField = new Point();
    SwingUtilities.convertPointToScreen(pointFrame, field);

    JFrame legende = new JFrame();
    legende.setSize(new Dimension(300, 300));
    legende.setUndecorated(true);
    Double x = pointField.getX();
    Double y = pointField.getY();
    legende.setLocation(x.intValue(), y.intValue());
    legende.setVisible(true);

    legende.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }


Ce qui me donne ça:

Guère satisfaisant, donc.

Puis j'ai tenté cela:
    public static void main(String[] arg) {
    JFrame frame = new JFrame();
    frame.setSize(new Dimension(600, 600));
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTextField field = new JTextField();
    field.setPreferredSize(new Dimension(300, 20));
    frame.setLayout(new FlowLayout());
    frame.add(field);
    Point pointFrame = new Point();
    SwingUtilities.convertPointToScreen(pointFrame, frame);
    Point pointField = new Point();
    SwingUtilities.convertPointToScreen(pointFrame, field);

    JFrame legende = new JFrame();
    legende.setSize(new Dimension(300, 300));
    legende.setUndecorated(true);
    System.out.println(pointField.getX() + " " + pointFrame.getX() + " "
        + pointField.getY() + " " + pointFrame.getY());
    Double x = pointField.getX() + pointFrame.getX();
    Double y = pointField.getY() + pointFrame.getX();
    legende.setLocation(x.intValue(), y.intValue());
    legende.setVisible(true);

    legende.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

Ce qui me donne ça:

Pas terrible, mais un peu mieux ^^ Et surtout, je crois que la position de la fenêtre (non décorée) n'est pas toujours la même.
J'ai tenté d'autres trucs, comme des GetLocation(), GetX(), GetY() sur le field, sans plus de succès.
Au fait, ce que je veux, c'est positionner la frame "legende" sous le textfield. (ce n'est pas pour faire un équivalent de 'setTipToolText, hein! ^^)
Donc est-ce que quelqu'un connaitrait une méthode pour récupérer la position absolue d'un élément à l'écran? ou alors: quelqu'un sait-il utiliser les fonctions que j'ai utilisées. Parce qu'il est possible aussi que je les utilise mal ^^.
Merci.

4 réponses

bob22mael Messages postés 4 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 14 juin 2010 1
1 juil. 2009 à 17:25
Merci de ta réponse.
Field.getX() et .getY() me renvoient toujours la même chose, quelle que soit la position de la frame dans laquelle est le field. Ils renvoient la position du composant à l'intérieur de son conteneur, non?
En fait, ce que je voudrais faire c'est:
Faire hériter une classe de JTextField, avec comme argument dans le constructeur un tableau, ou une ArrayList de String. Et quand je tape dans le JTextField, un popup apparait dessous pour faire des propositions qui se rapprochent de ce qu'on a tapé. Avec la possibilité de cliquer sur un élément proposé, ce qui a pour effet de remplir le JTextField.
Un truc du style Google ou bien ThunderBird, pour ne pas les citer ^^
Je ne sais pas si ça existe. Et d'ailleurs, même si ça existe, je préfère le coder moi même, pour m'entrainer.
Jusqu'à maintenant, ce que j'ai réussi à faire fonctionner c'est: l'apparition de la fenêtre avec les String qui me conviennent, lors d'un évènement clavier. Le problème se situe comme je l'avais dit au niveau du positionnement de la fenêtre qui doit apparaitre. Et j'ai aussi des problèmes pour la faire apparaitre en premier plan, sans perdre le focus sur le TextField.

Je ne connais pas la classe JPopUpMenu. Permet-elle de faire ce que j'ai envie de faire: afficher une liste de String qu'on peut ensuite sélectionner?
Pour l'instant, je gère ça avec une JList mise dans ma JFrame.
Merci
1
deglingo592003 Messages postés 77 Date d'inscription jeudi 27 novembre 2008 Statut Membre Dernière intervention 31 janvier 2014
1 juil. 2009 à 16:53
pour placer ta nouvelle frame en dessous tu peut faire un truc de ce genre :

frame2.setBounds(field.getX(), field.getY()+ hauteur, hauteur2, largeur2);

ou field et ton JTextfield, et Hauteur et la hauteur de ton JTextfield

puis hauteur2 et largeur2 la taille que tu souhaite donner à ta nouvelle frame (ici frame2)

par contre le "undecorate" ... cela à l'air bizarre mais on dirait qu'il place tout les composant comme si il n'y avait pas de "undecorate" et que tout à la fin il retire la décoration de fenêtre et provoque donc un décalage de la frame

il faudrai donc prendre en compte tout de même cela

sinon si tu veux juste integré ce champ dans ta frame, tu peux passer par un JPanel a la place qui ne te posera pas ce problème. ou bien peut etre qu'un JPopusmenu ferai al faire

il faut voir l'utilisation que tu veux en faire
0
bob22mael Messages postés 4 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 14 juin 2010 1
1 juil. 2009 à 20:49
Bon, j'ai un début de solution. C'est complètement  perfectible, vu que c'est un peu codé à l'arrache, mais c'est quand meme pas mal. merci [../auteur/DEGLINGO592003/1626485.aspx deglingo592003] de m'avoir orienté vers les Jpopupmenu, je me serais un peu embeté pour rien ^^
Me reste plus qu'à faire en sorte que les popupmenu disparaissent totalement quand je leur demande. En gros, faudrait un moyen de killer le pop up, moyen que j'ai pas trouvé, alors ça fait une petite tache quand le pop up est vide ^^
voilà ma classe, si ça peut intéresser quelqu'un:

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.Vector;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;

public class JtextFieldLegend extends JTextField {
    Vector<String> donnee = new Vector<String>();
    JList list = new JList();
    boolean afficher = false;
    JPopupMenu popup = new JPopupMenu();
    int x;
    int y;

    public JtextFieldLegend(Vector<String> entreesPossibles, Dimension d) {

    this.setPreferredSize(d);
    this.setFocusable(true);

    this.addKeyListener(new keyListener(this));

    donnee = entreesPossibles;
    list.setListData(donnee);

    }

    /**
     * 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;
    Vector<String> temp = new Vector<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 popupListener(this));
            popup.add(item);
        }

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

        }
    }

    }

    /**
     * Ecouteur du menu popup
     *
     */
    class popupListener implements ActionListener {
    JTextField field;

    public popupListener(JTextField field) {
        this.field = field;
    }

    public void actionPerformed(ActionEvent arg0) {
        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()
            - arg0.getComponent().getWidth() / 2 + 3, arg0
            .getComponent().getY()
            + (field.getHeight() - 7));
        field.requestFocus();
    }

    public void keyTyped(KeyEvent arg0) {

    }

    }

    public static void main(String[] arg) {
    Vector<String> v = new Vector<String>();
    v.add("blabla");
    v.add("tuututut");
    v.add("tutitititi");
    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);
    }
}
0
deglingo592003 Messages postés 77 Date d'inscription jeudi 27 novembre 2008 Statut Membre Dernière intervention 31 janvier 2014
2 juil. 2009 à 09:15
si tu obtient une petite tache de la taille de ta fenetre, c'est parceque ton interface graphique ne se met pas correctement à jours

je n'ai pas regardé tout ton code (manque de temps ^^) mais si tu invoque ton popup à l'aide d'un thread cela permettrai a ton interface de ce mettre à jour

à creuser dans ce sens ^^

le thread sera executer en parrallele du reste de ton application
0
Rejoignez-nous