다른 클래스의 정보로 JPanel을 어떻게 업데이트합니까?
-
12-12-2019 - |
문제
다음 예제 소스를 생성했으며 JTable에서 클릭한 행에 있는 정보가 있는 JLabel로 JPanel을 업데이트하려면 어떻게 해야 하는지 궁금합니다.
또한 여기 SO 멤버 몇 명 덕분에 샘플 코드를 꽤 많이 개선했기 때문에 이는 단지 단순한 예일 뿐이라는 점을 지적하고 싶었습니다.그래서 나는 배우는 방법으로 이 간단한 예제를 게시하고 있습니다.
SwingTesting(메인)
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();
}
});
}
}
테이블 창
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);
}
}
}
}
그래서 ListSelectionListener에서 해당 JPanel에 액세스하는 방법이 궁금합니다.패널을 TablePane 클래스에 전달해야 합니까?아니면 이 작업을 수행하는 더 적절한 방법이 있습니까?
또한 내 ListSelectionListener는 어떤 이유로 행 정보를 두 번 인쇄합니다. 루프를 엉망으로 만들었습니까?
편집하다
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)
}
복용만큼 간단한가요? final
끄다?
해결책
당신은 통과 할 수 있습니다 JLabel
에 반대하다 TablePane
객체(에서 TablePane
의 생성자를 사용하거나 사용자 정의를 제공하여 setLabel()
방법).그런 다음 사용할 수 있습니다 StringBuilder
라벨에 표시해야 하는 텍스트를 생성하고 setText()
라벨에 StringBuilder
객체(그것을 통해 toString()
방법).
나는 당신이 모든 것을 두 번 인쇄하고 있다고 생각합니다. valueChanged
메소드가 두 번 호출됩니다.현재 행 선택 취소에 대한 알림에 한 번, 새 행 선택에 대한 알림에 다시 한 번 표시됩니다.