Create info panel on mouseover in JTable? Tooltip might not be sufficient - java

I want to display an info box on mousing over a JTable cell using Java Swing, so there are multi-parts
How can I capture the mouse-over event in a table cell? I have to be able to set the cell content, then get data on it.
How can I display a panel/box with dynamic server data on mousing over that cell?
How can I cache the info panel/box so I don't have to query the server on every mouse over?
Example:
In table cell I enter: 94903. After tabbing or entering, the cell is set to the number. On mouse-over, it displays a box with Name, Address, Phone number, email, etc.
Thanks!

You could format the tooltip text using HTML, this would allow you to provide a complex structure of information to the tooltip without the need or expense of writing your own solution. The only problem is that the tooltip will be automatically discarded.
If this still doesn't suit, you could try:
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.*;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.Timer;
public class TestTable {
private Timer showTimer;
private Timer disposeTimer;
private JTable table;
private Point hintCell;
private MyPopup popup; // Inherites from JPopupMenu
public TestTable() {
showTimer = new Timer(1500, new ShowPopupActionHandler());
showTimer.setRepeats(false);
showTimer.setCoalesce(true);
disposeTimer = new Timer(5000, new DisposePopupActionHandler());
disposeTimer.setRepeats(false);
disposeTimer.setCoalesce(true);
table.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
int row = table.rowAtPoint(p);
int col = table.columnAtPoint(p);
if ((row > -1 && row < table.getRowCount()) && (col > -1 && col < table.getColumnCount())) {
if (hintCell == null || (hintCell.x != col || hintCell.y != row)) {
hintCell = new Point(col, row);
Object value = table.getValueAt(row, col);
// Depending on how the data is stored, you may need to load more data
// here...
// You will probably want to maintain a reference to the object hint data
showTimer.restart();
}
}
}
});
}
protected MyPopup getHintPopup() {
if (popup == null) {
// Construct the popup...
}
return popup;
}
public class ShowPopupActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (hintCell != null) {
disposeTimer.stop(); // don't want it going off while we're setting up
MyPopup popup = getHintPopup();
popup.setVisible(false);
// You might want to check that the object hint data is update and valid...
Rectangle bounds = table.getCellRect(hintCell.y, hintCell.x, true);
int x = bounds.x;
int y = bounds.y + bounds.height;
popup.show(table, x, y);
disposeTimer.start();
}
}
}
public class DisposePopupActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
MyPopup popup = getHintPopup();
popup.setVisible(false);
}
}
}
Now, I've not constructed the popup, I'd use the popup menu from Bob Sinclar's answer as well

Heres a good way to get the mouse over working I woud do this first then just output some text when your over it to check.
This shows a way to get a pop up menu to appear
And in regards to the cacheing i might store the last 10 values in memory and do a request from the server each time a new entry point is pinged ie you dont have it locally. And then maybe every minute update the last 10 hit incase their info changes.
another useful mouseover guide

Related

How to click and drag something without it deselecting

The program is an animation that creates a car and/or truck icon on the screen. The way I have it now it isn't working correctly. Specifically, the program is not clicking and dragging right. If one object is not-selected, once clicked on, it will become bolder to show that it is selected. From there we want to be able to drag it and the program will redraw the image wherever the mouse goes. If the image is un-selected, when I click and drag it, it works fine. The problem I am having is if the image is already selected. If the image is already selected, when I move the mouse over to it and click on it in order to move it to a different position, instead of moving, it is deselected instead so no movement occurs. Here is the code for the mousePressed and mouseDragged events. I think that is where the problem is, but I'm not sure what is causing it.
addMouseListener(new
MouseAdapter()
{
public void mousePressed(MouseEvent event)
{
mousePoint = event.getPoint();
for (SceneShape s : shapes)
{
if (s.contains(mousePoint))
s.setSelected(!s.isSelected());
}
repaint();
}
});
addMouseMotionListener(new
MouseMotionAdapter()
{
public void mouseDragged(MouseEvent event)
{
Point lastMousePoint = mousePoint;
mousePoint = event.getPoint();
for (SceneShape s : shapes)
{
if (s.isSelected())
{
double dx
= mousePoint.getX() - lastMousePoint.getX();
double dy
= mousePoint.getY() - lastMousePoint.getY();
s.translate((int) dx, (int) dy);
}
}
repaint();
}
});
Can someone help explain to me what is causing the program to deselect an already selected image when I drag it instead of moving it and how to fix this problem? Thanks.
One of the side effects of a drag operation is the fact that mouseClicked won't be called. Why is this important? Basically you can use this fact to make a decision about whether a object should be deselected or not within the mouseClicked event instead of something like mousePressed or mouseReleased.
It does require you to maintain some information about the current and previous states, so you know whether the object was just selected or was previously selected, but the basic idea works well.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class WhatADrag {
public static void main(String[] args) {
new WhatADrag();
}
public WhatADrag() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Rectangle> boxes;
private Rectangle selected;
public TestPane() {
boxes = new ArrayList<>(25);
int x = 0;
int y = 0;
for (int index = 0; index < 10; index++) {
boxes.add(new Rectangle(x, y, 100, 100));
x += 25;
y += 25;
}
MouseAdapter ma = new MouseAdapter() {
private Rectangle previous;
private Point delta;
#Override
public void mousePressed(MouseEvent e) {
List<Rectangle> reversed = new ArrayList<>(boxes);
Collections.reverse(reversed);
previous = selected;
if (selected == null || !selected.contains(e.getPoint())) {
for (Rectangle box : reversed) {
if (box.contains(e.getPoint())) {
selected = box;
delta = new Point(e.getX() - selected.x, e.getY() - selected.y);
repaint();
break;
}
}
if (selected != null) {
boxes.remove(selected);
boxes.add(boxes.size() - 1, selected);
}
} else if (selected != null) {
delta = new Point(e.getX() - selected.x, e.getY() - selected.y);
}
}
#Override
public void mouseClicked(MouseEvent e) {
if (selected == previous && selected != null && selected.contains(e.getPoint())) {
selected = null;
repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (selected != null) {
int x = e.getX() - delta.x;
int y = e.getY() - delta.y;
selected.x = x;
selected.y = y;
repaint();
}
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Rectangle box : boxes) {
if (box != selected) {
g2d.setColor(Color.BLUE);
g2d.fill(box);
g2d.setColor(Color.BLACK);
g2d.draw(box);
}
}
if (selected != null) {
g2d.setColor(Color.CYAN);
g2d.fill(selected);
g2d.setColor(Color.BLUE);
g2d.draw(selected);
}
g2d.dispose();
}
}
}
I am just so lost. I am looking at all this code and don't even understand what it is doing.
Yeah, I feel like this about my code a lot.
Basically...
First: mousePressed is called, I reverse my list of objects, because the top most component will be the last in the list (this is my requirement), I store the currently selected object in the previous variable, I use this to determine if there has been a change in selection or not. I check to see if the user clicked the selected object or not, if they did, we can basically skip every thing else. If not, we determine what they clicked, if anything. The delta is simply the difference between the place they clicked and the location of the object, this is used to make the drag more natural
If no drag occurs: mouseClicked is called. We test to see if the selected object is equal to the previous object and if the mouse was clicked within the selected object, if these are true, then the currently selected object should be deselected. Otherwise the user has basically just changed the selection, so we don't want to immediately deselect it.
Else if a drag occurs: mouseDragged is called. We simply check to see if something is selected, we calculate the difference between the current mouse position and the "click offset" and update the position of the selected object
Clear as mud :P
One thing to also remember is mouseReleased will always be called after mousePressed, even if mouseClicked isn't (which is called after mouseReleased when no dragging occurs).

Components in JList are Hidden by White Square Thing Until Clicked

In a project I've been working on, I noticed that all the JList items in my JScrollPane are hidden until the JScrollPane/JList has been clicked. The weird part is it's not completely covered. There's this white box with a transparent border that spreads out over the whole thing, covering all but a few pixels on all edges.
Pictures:
As you can see, there is this white block in the middle - notice the pink "border":
Now, once I click that white box, it goes away:
I know the magenta looks horrible, but I'm using it for contrast.
Which leads me to my question: how do I get rid of that obnoxious white box?
Here is my code:
public static void listJars(File f)
{
JCheckBox firstBox = null;
DefaultListModel<JCheckBox> model = new DefaultListModel<>();
if(mainGUI.checkList != null)
{
//System.out.println("Already exists lol: " + mainGUI.checkList.getName());
mainGUI.pluginList.remove(mainGUI.checkList);
}
//mainGUI.pluginList.repaint();
File[] files = new File(f.getPath()).listFiles();
if (files != null)
{
for (File file : files)
{
if (file.getName().endsWith(".jar") || file.getName().endsWith("._jar"))
{
JCheckBox cb = new JCheckBox(file.getName());
if(firstBox == null)
{
firstBox = cb;
}
cb.setSelected(file.getName().endsWith(".jar"));
cb.setVisible(true);
cb.setText(file.getName());
model.addElement(cb);
cb.repaint();
}
}
}
JCheckBoxList jCheckBoxList = new JCheckBoxList(model, mainGUI.textField1.getText());
jCheckBoxList.setName("pluginCheckboxList");
jCheckBoxList.setSize(mainGUI.pluginList.getSize());
mainGUI.pluginList.add(jCheckBoxList);
mainGUI.checkList = jCheckBoxList;
jCheckBoxList.setVisible(true);
jCheckBoxList.setVisibleRowCount(10);
}
And ten there's my JCheckBoxList class.
package Components;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
#SuppressWarnings("serial")
public class JCheckBoxList extends JList<JCheckBox>
{
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
protected String lastPath;
public JCheckBoxList(final String lastPath)
{
this.lastPath = lastPath;
setCellRenderer(new CellRenderer());
setBackground(Color.magenta);
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
int index = locationToIndex(e.getPoint());
if (index != -1)
{
JCheckBox checkBox = getModel().getElementAt(index);
checkBox.setSelected(!checkBox.isSelected());
repaint();
final String oldname = checkBox.getText();
if (!checkBox.isSelected())
{
checkBox.setName(checkBox.getText().substring(0, checkBox.getText().length() - 4) + "._jar");
}
else
{
checkBox.setName(checkBox.getText().substring(0, checkBox.getText().length() - 5) + ".jar");
}
System.out.println("Changed! Sel: " + checkBox.isSelected() + ", Name: " + checkBox.getName());
checkBox.setText(checkBox.getName());
String base = new File(lastPath).getParent() + "/plugins/";
boolean rename = new File(base + oldname).renameTo(new File(base + checkBox.getText()));
}
}
});
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
public JCheckBoxList(ListModel<JCheckBox> model, String lastPath)
{
this(lastPath);
setModel(model);
}
protected class CellRenderer implements ListCellRenderer<JCheckBox>
{
public Component getListCellRendererComponent(
JList<? extends JCheckBox> list, JCheckBox value, int index,
boolean isSelected, boolean cellHasFocus)
{
//Drawing checkbox, change the appearance here
value.setBackground(isSelected ? getSelectionBackground()
: getBackground());
value.setForeground(isSelected ? getSelectionForeground()
: getForeground());
value.setEnabled(isEnabled());
value.setFont(getFont());
value.setFocusPainted(false);
value.setBorderPainted(true);
value.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0));
return value;
}
}
}
And then there's my scroll pane, which has these settings (using the Intelliji IDEA UI designer):
Any ideas?
mainGUI.pluginList.add(jCheckBoxList);
mainGUI.checkList = jCheckBoxList;
jCheckBoxList.setVisible(true);
jCheckBoxList.setVisibleRowCount(10);
Looks to me like you are dynamically adding components to a visible GUI.
When you do this the basic code is:
panel.add(...);
panel.revalidate();
panel.repaint();
You should set the visibleRowCount() before the above code is executed.
Also:
Swing components are visible by default so you don't need the setVisible(true).
You may want to consider using a one column JTable since it already supports a checkbox renderer and editor.
Edit:
The solution I gave you above is the general solution. A scroll pane is different, you should only ever add a component to the viewport.
Based on your incorrect solution you should be using:
//mainGUI.pluginList.add(jCheckBoxList);
mainGUI.pluginList.setViewportView(jCheckBoxList);
The problem with posting only a few random lines of code is that we don't know the full context of the code. I did not realize "pluginList" was actually a scrollpane. Usually the variable name will have scroll or scrollpane in the name.
mainGUI.pluginList.setViewportView(mainGUI.checkList); // pluginList is the JScrollPane.
Do that, and it fixes everything! Put it in with my listJars method.

adjust width of jcombobox dropdown menu

Is there a way to adjust the drop-down window size of a JCombobox?
let's say I have:
comArmor.setBounds(81, 102, 194, 26);
But when the user selects the box and the drop-down list pops up, i'd like for the drop-down window to expand so that a long line of text will be displayed entirely (say size x of 300).
Is this possible?
Small hack to get pop up menu size bigger enough to show items even though the combo box size could be smaller
Source: http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough
import java.awt.Dimension;
import java.util.Vector;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
public class ComboBoxFullMenu<E> extends JComboBox<E> {
public ComboBoxFullMenu(E[] items) {
super(items);
addActionListener(this);
}
public ComboBoxFullMenu(Vector<E> items) {
super(items);
addActionListener(this);
}
public ComboBoxFullMenu(ComboBoxModel<E> aModel) {
super(aModel);
addActionListener(this);
}
/**
* Small hack to get pop up menu size bigger enough to show items even though
* the combo box size could be smaller
* */
private boolean layingOut = false;
#Override
public void doLayout(){
try{
layingOut = true;
super.doLayout();
}finally{
layingOut = false;
}
}
#Override
public Dimension getSize(){
Dimension dim = super.getSize();
if ( !layingOut ) {
dim.width = Math.max(dim.width, getPreferredSize().width);
}
return dim;
}
}
Not sure if there is built in functionality for this already, but you could always have a ActionListener which listens for selection changes and then programmatically set the width of the JComboBox to the length of the selected content (getSelectedItem()) when it changes.
box.addActionListener (new ActionListener () {
public void actionPerformed(ActionEvent e) {
String item = comboBox.getSelectedItem().toString();
comboBox.setBounds(81, 102, item.length * CONSTANT, 26);
}
});
It seems a bit hacky to me and you might have to play around with this idea to get it to work.
I hope this helps you!
Update:
JComboBox appears to have a setPrototypeDisplayValue(Object) method that is used to calculate component's preferred width based on the length of the parameter.
Sets the prototype display value used to calculate the size of the display for the UI portion.
I might consider using this instead.

Java swing component to show image grid

Its been a while since i built a desktop JAVA application.. after lots of documentation and doing implementation tests, i still have not found an image grid solution.
Either Java lacks such a ready-to-use component (?!) or you tell me to brush up my google-fu. :)
I have a very simple technical premises: a JDialog that allows the user to pick an image. Input is a Map<Integer, String> list that holds filenames. Output is the Integer key the user chose. GUI also is simple: user chooses 1 image using mouse or keyboard, and dialog closes. All images are 80x80px and loaded from filename, not a resource.
I tried several approaches so far this morning:
Search for components/widgets that show scrollable imagegrid that can flow to the left. (no dice)
Search for components/widgets that show scrollable imagegrid (no dice)
Search for any components/widgets/gui-libs (no dice .. do these even exist?!)
Try and implement myJList.setModel(), but i cant get it to just take my Map<> and show thumbnails. (overcomplicates!)
Try and implement myJPanel.setlayout(new FlowLayout(..)) with several myJPanel.add(new JButton(..)) which just creates a bunch of JButton on a JPanel, which each need a event handler. I wonder how scrolling and keyboard input is going to work out, and how i'm supposed to keep/reference my Map<> key values. (overcomplicates?)
In lieu of your answer, i am now working on the latter, which should work but i cant believe everyone needs to reinvent the same GUI wheel here. How to have the user select an image from my Map<Integer, String>? Are there JAVA libraries/widgets/components that i should look to avoid this?
I hope this isn't being modded down, i have no working implementation with error to show you guys.. this question is about how/where to find the components or what approaches would be better. Its 2014 and i cant believe that JAVA still requires me to build my own "GUI component" just to see some images.. not even Delphi or Mono does that.
If all you want is a grid of images, and having them selectable, consider using a JList, filling it with appropriate ImageIcons, and giving it a ListSelectionListener. In the Listener you can close the enclosing dialog when a selection has been made.
You state:
Try and implement myJList.setModel(), but i cant get it to just take my Map<> and show thumbnails. (overcomplicates!)
You need to use your Map to populate your ListModel, and set that Model to the JList's model.
For example:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
#SuppressWarnings("serial")
public class ImageGridPanel extends JPanel {
public static final String PATH = "http://images-2.drive.com.au/2011/";
public static final String[] CARS = {
"04/15/2308961/giulietta_1024-80x80.jpg",
"11/18/2781958/audi-a1-sportback_600-80x80.jpg",
"12/23/2856762/fiat-500-80x80.jpg",
"01/12/2129944/Honda-Civic-Sedan-concept-1_600-80x80.jpg",
"12/23/2856581/mini-roadster-80x80.jpg",
"12/23/2856571/hyundai-veloster-80x80.jpg",
"12/23/2856771/hyundai-i30-80x80.jpg",
"12/23/2856580/mini-coupe-80x80.jpg" };
private DefaultListModel<Car> carModel = new DefaultListModel<>();
final JTextField textField = new JTextField(20);
public ImageGridPanel() {
for (String carPath : CARS) {
String path = PATH + carPath;
try {
URL imgUrl = new URL(path);
BufferedImage img = ImageIO.read(imgUrl);
ImageIcon icon = new ImageIcon(img);
String name = carPath.substring(carPath.lastIndexOf("/"));
name = name.substring(1, name.lastIndexOf("-"));
carModel.addElement(new Car(name, icon));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
ShowGridAction showAction = new ShowGridAction("Car Grid", carModel);
JButton showGridBtn = new JButton(showAction);
add(showGridBtn);
add(textField);
}
private class ShowGridAction extends AbstractAction {
private CarGridPanel carGridPanel;
public ShowGridAction(String name, DefaultListModel<Car> carModel) {
super(name);
carGridPanel = new CarGridPanel(carModel);
}
public CarGridPanel getCarGridPanel() {
return carGridPanel;
}
#Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor((Component) e.getSource());
JDialog dialog = new JDialog(win, "Cars", ModalityType.APPLICATION_MODAL);
dialog.add(carGridPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
int x = dialog.getLocation().x;
int y = dialog.getLocation().y - 150;
dialog.setLocation(x, y);
dialog.setVisible(true);
Car selectedCar = carGridPanel.getSelectedCar();
if (selectedCar != null) {
textField.setText(selectedCar.getName());
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ImageGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ImageGridPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Car {
String name;
Icon icon;
public Car(String name, Icon icon) {
this.name = name;
this.icon = icon;
}
public String getName() {
return name;
}
public Icon getIcon() {
return icon;
}
}
#SuppressWarnings("serial")
class CarGridPanel extends JPanel {
private JList<Car> carList = new JList<>();
private Car selectedCar;
public CarGridPanel(ListModel<Car> model) {
carList.setModel(model);
carList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
carList.setVisibleRowCount(2);
carList.setCellRenderer(new DefaultListCellRenderer() {
#Override
public Component getListCellRendererComponent(JList<?> list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
Car carValue = (Car) value;
value = carValue.getIcon();
} else {
value = "";
}
return super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
}
});
setLayout(new BorderLayout());
add(new JScrollPane(carList));
carList.addListSelectionListener(new ListListener());
}
public Car getSelectedCar() {
return selectedCar;
}
private class ListListener implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent e) {
selectedCar = carList.getSelectedValue();
Window win = SwingUtilities.getWindowAncestor(CarGridPanel.this);
win.dispose();
}
}
}
No, Java doesn't have what you want.
Java is a general-purpose programming language, not a toolset, particularly not a specialized desktop GUI toolset. This is not a denigration of the language, just a statement of a purpose that it was not developed to fulfill.
If Delphi or Mono or anything has your particular widget, then I suggest you program in that, instead. This is not a denigration of you, just an observation that, if you do not want to put together the widget you want from lower-level components and code, then Java is not the right language/tool for you to use to do it.
As for not believing that Java "still requires" you to build your own component, I can only say that you don't get to choose which languages provide which features. I'm just as glad Java isn't littered with your component and the hundreds of others that people like you would come up with that they think Java should provide. It's big enough as it is.

how to control focus in JTable

What I want to do is when user finish editing of data in table cell to move focus onto another cell depending of what user entered, and to turn that cell into editing mode so user can start typing immediately with no additional action. This way user can focus on his work and software will do the 'thinking' about which cell should be edited next.
Simple task which does not look so simple in real life ... anyone some idea?
Please try this example.
It should let you navigate through the table by entering the values u, d, l, r for Up, Down, Left, Right.
Hope that this will give you an idea about how to do it.
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class Test extends JFrame {
private JTable table;
private TableModel tableModel;
public Test() {
tableModel = new DefaultTableModel(5, 5);
table = new JTable(tableModel);
table.setColumnSelectionAllowed(true);
getContentPane().add(table);
Action handleEnter = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
table.getCellEditor().stopCellEditing(); // store user input
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
String val = String.valueOf(table.getValueAt(row, col)).toLowerCase();
if (val.equals("u"))
--row;
else if (val.equals("d"))
++row;
else if (val.equals("l"))
--col;
else if (val.equals("r"))
++col;
if ( row >= 0 && row < tableModel.getRowCount()
&& col >= 0 && col < tableModel.getColumnCount()) {
table.changeSelection(row, col, false, false);
table.editCellAt(row, col);
}
}
};
// replace action for ENTER, since next row would be selected automatically
table.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "handleEnter");
table.getActionMap().put("handleEnter", handleEnter);
}
public static void main(String[] args) {
Test test = new Test();
test.setSize(800, 600);
test.setVisible(true);
}
}
You should add a KeyListener to the JTable to get all typed Characters.
After the user presses Enter, you should check the word the user has typed.
Write your own FocusTraversalPolicy to set it to the Table
table.setFocusTraversalPolicy(policy)
The FocusTraversalPolicy describes which component gets the next focus.
After this you can call
FocusManager.getCurrentManager().focusNextComponent();
EDIT: I did not test this, it is just an idea.

Categories