J'ai besoin d'afficher les cellules sélectionnées/focalisées dans un tableau de bord. JTable
avec un JComboBox
si la colonne en question utilise le combo comme éditeur. L'objectif est d'indiquer aux utilisateurs que les cellules de la colonne sont éditées à l'aide d'une combinaison plutôt qu'à l'aide de la fonction JTextField
.
Mon problème est que pour d'autres LookAndFeels
que Metal il est impossible de définir la sélection de fond du tableau à la combobox. Si l'on clique ou navigue avec le clavier vers une "colonne combo", la cellule sélectionnée est rendue par la combo avec le fond par défaut.
Metal L&F fonctionne comme je le souhaite, mais ce n'est pas une option car nos clients utilisent soit Substance/Nimbus/Windows L&F et cela ne fonctionne pour aucun d'entre eux.
J'espère avoir été assez clair, toute aide est appréciée !
Sélectionnez les cellules de la "colonne Combo" de ce SSCCE pour voir ce que je veux dire :
import java.awt.Component;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel;
public class RenderSelectedCellWithComboSSCCE extends JFrame
{
RenderSelectedCellWithComboSSCCE()
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
add(new JScrollPane(createTable()));
pack();
}
private JTable createTable()
{
TableModel model = new DefaultTableModel(
new Object [][] {{"A", "Item 0"},
{"B", "Item 1"},
{"C", "Item 2"},
{"D", "Item 3"},
{"E", "Item 4"}},
new String [] {"TextField", "Combo"});
JTable table = new JTable(model);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
DefaultCellEditor editor = new DefaultCellEditor(new JComboBox(new Object[]{"Item 0", "Item 1", "Item 2", "Item 3", "Item 4"}));
editor.setClickCountToStart(2);
table.getColumnModel().getColumn(1).setCellEditor(editor);
table.getColumnModel().getColumn(1).setCellRenderer(new ComboCellRenderer());
return table;
}
/**
* Renderer that demonstrates problem rendering selected cells with a combo with selection background.
*/
private static class ComboCellRenderer implements TableCellRenderer
{
final TableCellRenderer defaultRenderer;
final JComboBox combo;
ComboCellRenderer()
{
defaultRenderer = new DefaultTableCellRenderer();
combo = new JComboBox();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if (hasFocus && table != null && table.isCellEditable(row, column))
{
combo.setModel(new DefaultComboBoxModel(new Object[]{value}));
combo.setSelectedItem(value);
combo.setBackground(table.getSelectionBackground()); // This only have desired effect for Metal L&F
return combo;
}
else
{
return defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
setLookAndFeel();
new RenderSelectedCellWithComboSSCCE().setVisible(true);
}
private void setLookAndFeel()
{
try
{
//UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); // Metal works fine
UIManager.setLookAndFeel(new NimbusLookAndFeel());
//UIManager.setLookAndFeel(new WindowsLookAndFeel());
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
//UIManager.setLookAndFeel("org.jvnet.substance.SubstanceLookAndFeel");
}
catch (Exception e)
{
throw new RuntimeException("Failed to set LookAndFeel", e);
}
}
});
}
}