Is it possible to get location of selected element in JList? I would like to get it to place JFrame just below clicked option.
Asked
Active
Viewed 2,797 times
2 Answers
6
You'll want to use JList#getCellBounds
int selectedIndex = list.getSelectedIndex();
Rectangle bounds = list.getSelectedBounds(selectedIndex, selectedIndex);
This will give you the location of the selected item within context to the JList
, you'll need to translate this to screen space...
Point p = bounds.getLocation();
SwingUtilities.convertPointToScreen(p, list);
You may also want to take a look at The Use of Multiple JFrames: Good or Bad Practice?
For example...
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class List {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new List();
}
public List() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
final JFrame selected = new JFrame("Selected");
selected.add(new JLabel("Here I am"));
selected.pack();
DefaultListModel model = new DefaultListModel();
for (int index = 0; index < 1000; index++) {
model.addElement("#" + index);
}
final JList list = new JList(model);
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
int index = list.getSelectedIndex();
Rectangle bounds = list.getCellBounds(index, index);
Point p = bounds.getLocation();
p.y += bounds.height;
SwingUtilities.convertPointToScreen(p, list);
p.x -= selected.getWidth();
selected.setLocation(p);
selected.setVisible(true);
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(list));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

Community
- 1
- 1

MadProgrammer
- 343,457
- 22
- 230
- 366
3
You can use indexToLocation()
method of JList
, for example:
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class TestFrame extends JFrame {
public TestFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
pack();
setVisible(true);
}
private void init() {
final JPopupMenu menu = new JPopupMenu("test");
menu.add(new JMenuItem("1"));
final JList<String> list = new JList<String>(new String[]{"1","2","3"});
list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
int selectedIndex = list.getSelectedIndex();
if(selectedIndex != -1){
Point indexToLocation = list.indexToLocation(selectedIndex);
Rectangle cellBounds = list.getCellBounds(selectedIndex, selectedIndex);
menu.show(list, indexToLocation.x, indexToLocation.y+cellBounds.height);
}
}
});
add(list);
}
public static void main(String... strings) {
new TestFrame();
}
}

alex2410
- 10,904
- 3
- 25
- 41
-
Interesting, but it doesn't provide the height of the selected item, meaning that your `JPopupMenu` will overlay the selected item...which as I understand it, isn't what the OP wanted...learnt something though ;) – MadProgrammer Jun 05 '14 at 11:33
-
@MadProgrammer , You are right, but I think OP can change `menu.show(list, indexToLocation.x, indexToLocation.y);` for showing in another location – alex2410 Jun 05 '14 at 11:41