Buongiorno
Ripropongo un estratto del problema che ho esposto nel primo post sperando che con un esempio pratico qualcuno mi possa dare una mano
Facendo girare l'esempio (trascurato ma funzionale a dimostrare il mio problema) si notano in console i passaggi nel focustraversalpolicy
Prova1: si preme semplicemente TAB o ShiftTab
In console si vedono i passaggi nei metodi getComponentAfter e getComponentBefore; in particolare si vede che, non essendo le celle in edit, nel caso del secondo componente, viene ritornato il componente JScrollPane. Va bene cosi
Prova2: si clicca su una cella JTable, si scrive qualcosa (per entrare in edit) e si preme TAB
In console si vede il passaggio nel metodo getComponentAfter ; in particolare si vede che, avendo il focus la JTable, viene ritornato il componente JTable. Va bene cosi
Prova3: si clicca su una cella JTable, si scrive qualcosa (per entrare in edit) e si preme ShiftTAB
Non succede niente almeno a livello di focustraversalpolicy
Se si preme ancora ShiftTab
In console si vede il passaggio nel metodo getComponentBefore ; in particolare si vede che viene ritornato il componente JTextField usato per l'edit della cella!!!!
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Prova2
{
public static final Double VideoDefaultFontIncrementWidth = 0.92;
public static final Double VideoDefaultFontIncrementHeight = 1.5;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new Prova2();
}
});
}
public Prova2()
{
JFrame frame = new JFrame("Prova");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//
Object[] columnHeaders = {"Codice", "Nome", "Prezzo", "Data", "Noedit"};
Object rows[][] = {
{ "A", "About", 44.36, null, "aa" },
{ "B", "Boy", 44.84, null, "aa" },
{ "C", "Cat", 463.63, null, "aa" },
{ "D", "Day", 27.14, null, "aa" },
{ "E", "Eat", 44.57, null, "aa" },
{ "F", "Fail", 23.15, null, "aa" },
{ "G", "Good", 4.40, null, "aa" },
{ "H", "Hot", 24.96, null, "aa" },
{ "I", "Ivey", 5.45, null, "aa" },
{ "J", "Jack", 49.54, null, "aa" },
{ "K", "Kids", 280.00, null, "aa" },
{ "2A", "About", 44.36, null, "aa" },
{ "2B", "Boy", 44.84, null, "aa" },
{ "2C", "Cat", 463.63, null, "aa" },
{ "2D", "Day", 27.14, null, "aa"},
{ "2E", "Eat", 44.57, null, "aa" },
{ "2F", "Fail", 23.15, null, "aa" },
{ "2G", "Good", 4.40, null, "aa" },
{ "2H", "Hot", 24.96, null, "aa" },
{ "2I", "Ivey", 5.45, null, "aa" },
{ "2J", "Jack", 49.54, null, "aa" },
{ "2K", "Kids", 280.00, null, "aa" } };
//
// text 1
JTextField Text1 = new JTextField("");
Text1.setName("Text1");
frame.add(Text1, BorderLayout.NORTH);
//
// JTable soluzione 2
JTable myTable = new JTable(rows, columnHeaders);
myTable.setName("Table");
myTable.setFillsViewportHeight(true);
myTable.putClientProperty("autoStartsEdit", true);
myTable.putClientProperty("terminateEditOnFocusLost", true);
////myTable.setAutoCreateColumnsFromModel(false);
////myTable.getSelectionModel().addListSelectionListener(new myListSelectionHandler());
////myTable.addFocusListener(new myTableFocusListener());
// disabilita CtrlTab e CtrlShiftTab come uscita di campo jTable
// che tornano ad essere sentiti come traversal focus del tabbedpane per tab successivo e precedente
////myTable.setFocusTraversalKeysEnabled(false);
// disabilita Tab e ShiftTab come spostamento tra celle
// che tornano ad essere sentiti come traversal focus del tabbedpane per campo successivo e precedente
ActionMap myTableActionMap = myTable.getActionMap();
myTableActionMap.put("selectPreviousColumnCell", new myPreviousFocusHandler());
myTableActionMap.put("selectNextColumnCell", new myNextFocusHandler());
for (int i = 0; i < myTable.getColumnCount()-1; i++)
{
JTextField myTextField = new JTextField();
myTable.getColumn(columnHeaders[i]).setCellEditor(new DefaultCellEditor(myTextField));
}
JScrollPane pane = new JScrollPane(myTable);
frame.add(pane, BorderLayout.CENTER);
//
// text2
JTextField Text2 = new JTextField("");
Text2.setName("Text1");
frame.add(Text2, BorderLayout.SOUTH);
//
// frame
frame.setFocusTraversalPolicy(new MyFocusTraversalPolicy());
frame.setSize(800, 400);
frame.setVisible(true);
}
public static class MyFocusTraversalPolicy extends FocusTraversalPolicy
{
@Override
public Component getComponentAfter(Container arg0, Component arg1)
{
System.out.println("getComponentAfter: "+arg1.toString());
JRootPane myRootPane=(JRootPane)arg0.getComponent(0);
JPanel myPanel = (JPanel) myRootPane.getLayeredPane().getComponent(0);
if (arg1 instanceof JPanel == true)
{
return getFirstComponent(arg0);
}
int myNewPosition = 0;
myNewPosition = myComponentPosition(myPanel, arg1);
myNewPosition = myComponentNext(myPanel, myNewPosition, 1);
if (myNewPosition > -1)
{
return myComponent(myPanel, myNewPosition);
}
else
{
return getFirstComponent(arg0);
}
}
@Override
public Component getComponentBefore(Container arg0, Component arg1)
{
System.out.println("getComponentBefore: "+arg1.toString());
JRootPane myRootPane=(JRootPane)arg0.getComponent(0);
JPanel myPanel = (JPanel) myRootPane.getLayeredPane().getComponent(0);
if (arg1 instanceof JPanel == true)
{
return getFirstComponent(arg0);
}
int myNewPosition = 0;
myNewPosition = myComponentPosition(myPanel, arg1);
myNewPosition = myComponentNext(myPanel, myNewPosition, -1);
if (myNewPosition > -1)
{
return myComponent(myPanel, myNewPosition);
}
else
{
return getLastComponent(arg0);
}
}
@Override
public Component getDefaultComponent(Container arg0)
{
System.out.println("getDefaultComponent: ");
JRootPane myRootPane=(JRootPane)arg0.getComponent(0);
JPanel myPanel = (JPanel) myRootPane.getLayeredPane().getComponent(0);
return myPanel.getComponent(0);
}
@Override
public Component getFirstComponent(Container arg0)
{
System.out.println("getFirstComponent: ");
JRootPane myRootPane=(JRootPane)arg0.getComponent(0);
JPanel myPanel = (JPanel) myRootPane.getLayeredPane().getComponent(0);
return myPanel.getComponent(0);
}
@Override
public Component getLastComponent(Container arg0)
{
System.out.println("getLastComponent: ");
JRootPane myRootPane=(JRootPane)arg0.getComponent(0);
JPanel myPanel = (JPanel) myRootPane.getLayeredPane().getComponent(0);
return myPanel.getComponent(myPanel.getComponentCount()-1);
}
// ritorna la posizione del componente dato
private int myComponentPosition(Container parm_Container, Component parm_Component)
{
for (int i = 0; i < parm_Container.getComponentCount(); i++)
{
if (parm_Container.getComponent(i) == parm_Component)
{
return i;
}
}
return -1;
}
// ritorna la posizione del componente successivo o precedente rispetto al dato
private int myComponentNext(Container parm_Container, int parm_Position, int parm_Increment)
{
for (int i = parm_Position + parm_Increment; i > -1 && i < parm_Container.getComponentCount(); i = i + parm_Increment)
{
if (parm_Container.getComponent(i).isEnabled() && parm_Container.getComponent(i).isFocusable())
{
return i;
}
}
return -1;
}
// ritorna il componente alla posizione
private Component myComponent(Container parm_Container, int parm_Position)
{
return parm_Container.getComponent(parm_Position);
}
}
public class myPreviousFocusHandler extends AbstractAction
{
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent arg0)
{
KeyboardFocusManager myManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
myManager.focusPreviousComponent();
}
}
public class myNextFocusHandler extends AbstractAction
{
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent arg0)
{
KeyboardFocusManager myManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
myManager.focusNextComponent();
}
}
}