Comment mettre à jour un JPanel avec des informations provenant d’une autre classe ?
-
12-12-2019 - |
Question
J'ai créé l'exemple de source suivant et je me demande ce que je dois faire pour mettre à jour mon JPanel avec un JLabel contenant les informations situées à partir de la ligne cliquée dans la JTable.
Je voulais également noter qu'il ne s'agit que d'un simple exemple car j'ai considérablement amélioré l'exemple de code grâce à quelques membres SO ici.Je publie donc cet exemple simple pour apprendre
SwingTesting (principal)
public class SwingTesting {
private final JFrame frame;
private final TablePane tablePane;
private final JSplitPane splitPane;
private final JPanel infoPanel;
private final JLabel infoLabel;
public SwingTesting() {
tablePane = new TablePane();
infoPanel = new JPanel();
frame = new JFrame();
infoLabel = new JLabel(); //this is the panel i want to add the label to
infoPanel.add(infoLabel);
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tablePane, infoPanel);
frame.add(splitPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SwingTesting();
}
});
}
}
Volet de table
public class TablePane extends JPanel {
private final JTable table;
private final TableModel tableModel;
private final ListSelectionModel listSelectionModel;
public TablePane() {
table = new JTable();
tableModel = createTableModel();
table.setModel(tableModel);
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
table.add(table.getTableHeader(), BorderLayout.PAGE_START);
table.setFillsViewportHeight(true);
listSelectionModel = table.getSelectionModel();
table.setSelectionModel(listSelectionModel);
listSelectionModel.addListSelectionListener(new SharedListSelectionHandler());
table.setSelectionModel(listSelectionModel);
this.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 1;
gbc.gridwidth = 3;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.ipadx = 2;
gbc.ipady = 2;
gbc.weightx = 1;
gbc.weighty = 1;
this.add(new JScrollPane(table), gbc);
}
private TableModel createTableModel() {
DefaultTableModel model = new DefaultTableModel(
new Object[] {"Car", "Color", "Year"}, 0
){
@Override public boolean isCellEditable(int row, int column) {
return false;
}
};
addTableData(model);
return model;
}
private void addTableData(DefaultTableModel model) {
model.addRow(new Object[] {"Nissan", "Black", "2007"});
model.addRow(new Object[] {"Toyota", "Blue", "2012"});
model.addRow(new Object[] {"Chevrolet", "Red", "2009"});
model.addRow(new Object[] {"Scion", "Silver", "2005"});
model.addRow(new Object[] {"Cadilac", "Grey", "2001"});
}
class SharedListSelectionHandler implements ListSelectionListener {
//When selection changes i want to add a label to the panel
//currently it just prints out the info from the selected row
@Override
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
String contents = "";
if(lsm.isSelectionEmpty()) {
System.out.println("<none>");
} else {
int minIndex = lsm.getMinSelectionIndex();
int maxIndex = lsm.getMaxSelectionIndex();
for(int i = minIndex; i <= maxIndex; i++) {
if(lsm.isSelectedIndex(i)) {
for(int j = 0; j < table.getColumnCount(); j++) {
contents += table.getValueAt(i, j) + " ";
}
}
}
System.out.println(contents);
}
}
}
}
Je me demande donc comment accéder à ce JPanel à partir de ListSelectionListener.Dois-je simplement transmettre le panneau à la classe TablePane ?Ou existe-t-il une manière plus appropriée de procéder ?
De plus, mon ListSelectionListener imprime les informations de ligne deux fois pour une raison quelconque, ai-je gâché la boucle ?
MODIFIER
public class TablePane extends JPanel {
private final JTable table;
private final TableModel tableModel;
private final ListSelectionModel listSelectionModel;
private final displayPanel;
public TablePane() {
//removed code for reading purposes
}
//IDE says issue with thinking displayPanel may have already been initialized
public TablePane(JPanel panel) {
//this();
//displayPanel = panel;
}
//ListSelectionListener uses panel.add(jlabel)
}
Est-ce aussi simple que de prendre final
désactivé?
La solution
Vous pouvez passer le JLabel
s'opposer à la TablePane
objet (dans TablePane
le constructeur de ou en fournissant un personnalisé setLabel()
méthode).Ensuite, vous pouvez utiliser StringBuilder
pour créer le texte qui doit figurer sur l'étiquette et appeler setText()
sur l'étiquette avec le contenu du StringBuilder
objet (via son toString()
méthode).
Je crois que vous imprimez tout deux fois parce que le valueChanged
la méthode est appelée deux fois :une fois sur la notification de désélection de la ligne en cours, puis de nouveau sur la notification de sélection de la nouvelle ligne.