作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用 JTable 的选择处理程序时遇到问题。
该表每 15 秒从控件中的刷新线程更新一次。
我想在 JTable 中选择一行并提取列内容,我将使用它来构建文件名。
只要在刷新期间未选择第 0 行,一切就可以正常工作。但是,如果在触发刷新时选择了第 0 行,它看起来会在 setAppserverData 过程和事件处理程序之间跳转,直到它超过表的 rowCount 并且我收到 IndexOutOfBoundsException。
我是一名 Java 新手,这超出了我的知识范围,所以我很难弄清楚代码出了什么问题。我的直觉是,这与我试图实现 MVC 结构有关,但我未能以正确的方式分离代码。
// Controller
// Appserver worker
class AppserverWorker extends SwingWorker<Integer, Integer>{
protected Integer doInBackground() throws Exception{
// Check appservers
while(true){
theModel.readAppservData();
// Update action buttons
try {
if(!theModel.isStatusOk()){
theGui.actionButtonPanel.setAppServBtnColor("RED");
// theGui.actionButtonPanel.setButtonFlashOn();
}else theGui.actionButtonPanel.setAppServBtnColor("GREEN");
} catch (IllegalArgumentException e1) {
sysLogger.logMsg("SEVERE",e1.getMessage());
JOptionPane.showMessageDialog(null, e1.getMessage());
}
// Update GUI
theGui.extAppServPanel.setAppserverData(theModel.getAppservData());
// Sleep refresh time
// TODO read refresh from init table
try {
Thread.sleep(appServRefreshTime);
} catch (InterruptedException e) {}
}
}
// List selection handler
class SharedListSelectionHandler implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()){ // To avoid double trigger of listener
System.out.println(">>>>>>>>> Selection list handler >>>>>>>>");
String fileName = null;
String fileExt = ".txt";
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
try {
int selectedRow = lsm.getAnchorSelectionIndex(); // Get the row clicked
if (selectedRow>=0){ // If -1 no row selected
fileName = theGui.extAppServPanel.getAppservName(selectedRow)+fileExt; // Get appserver name and build file name
theModel.readCollectFile(InitParameters.collectFilePath, fileName); // Read collect file
theGui.extAppServPanel.setAppservInfo(theModel.getCollectFileContent()); // Fill the text panel with collect file
}
}
catch(FileNotFoundException e1){
sysLogger.logMsg("SEVERE",this.getClass().getSimpleName()+": Collect file "+fileName+" is missing");
JOptionPane.showMessageDialog(null, "Collect file "+fileName+" is missing");
}
catch(IOException e1){
sysLogger.logMsg("SEVERE",this.getClass().getSimpleName()+": System error: An I/O error occurred");
System.err.println("System error: An I/O error occurred");
System.exit(0);;
}
}
}
}
// View
public class ExtAppServPanel extends JPanel {
private JTable table;
private DefaultTableModel model;
private JTextArea textAreaInfo;
private JButton btnSaveInfo;
private List colData;
public boolean ignoreTableChanges = false;
/**
* Constructor
*/
public ExtAppServPanel() {
System.out.println(this.getClass().getSimpleName()+": Constructor");
setLayout(new MigLayout("", "[350:376.00,grow,leading]", "[100px:100,grow][][48.00,grow][]"));
this.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Application servers info", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
// Set up table
String[] columnNames = {"Server name", "Type","Status"};
model = new DefaultTableModel(null,columnNames);
table = new JTable(model){
// Color code rows
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
Component comp = super.prepareRenderer(renderer, row, col);
if (!isRowSelected(row)){
comp.setBackground(getBackground());
int modelRow = convertRowIndexToModel(row);
String type = (String)getModel().getValueAt(modelRow, 2);
if ("FAIL".equals(type)) comp.setBackground(Color.RED);
if ("WARNING".equals(type)) comp.setBackground(Color.YELLOW);
}
return comp;
}
};
// Set grid
table.setGridColor(Color.LIGHT_GRAY);
// Set width and alignment
table.getColumnModel().getColumn(1).setMinWidth(200);
table.getColumnModel().getColumn(1).setMaxWidth(200);
table.getColumnModel().getColumn(1).setPreferredWidth(200);
table.getColumnModel().getColumn(2).setMinWidth(75);
table.getColumnModel().getColumn(2).setMaxWidth(75);
table.getColumnModel().getColumn(2).setPreferredWidth(75);
// Add scrollpane
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
table.setFillsViewportHeight(true);
this.add(scrollPane, "cell 0 0,grow");
// Set up text area
JLabel lblDetails = new JLabel("Details");
this.add(lblDetails, "cell 0 1,alignx leading");
textAreaInfo = new JTextArea();
textAreaInfo.setBackground(Color.BLACK);
textAreaInfo.setForeground(Color.GREEN);
textAreaInfo.setEditable(false);
textAreaInfo.setFont(new Font("Lucida Console",Font.PLAIN,10));
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setViewportView(textAreaInfo);
this.add(scrollPane_1, "cell 0 2,grow");
// Save button
btnSaveInfo = new JButton("Save");
add(btnSaveInfo, "cell 0 3,alignx right");
}
/*
* Setters and getters
*/
public void setAppserverData(ArrayList<ArrayList<String>> dataRecord) {
ArrayList<String> dataCol = new ArrayList<String>();
// Init values array from result set
try {
model.setRowCount(0); // <<<<<<<<<< Problem
String[] arrayRow;
String status = "Ok";
// Get first row from list
dataCol = dataRecord.get(0);
arrayRow = new String[dataCol.size()];
arrayRow[0] = dataCol.get(2);
arrayRow[1] = dataCol.get(1);
arrayRow[2] = dataCol.get(4);
for (int i = 0; i < dataRecord.size(); i++){
dataCol = dataRecord.get(i);
// Check status
if (dataCol.get(4).toUpperCase().equals("FAIL")){
status = "FAIL";
}else if (dataCol.get(4).toUpperCase().equals("WARNING")){
status = "WARNING";
}
if (!dataCol.get(2).toUpperCase().equals(arrayRow[0].toUpperCase())){
arrayRow[2] = status; // Override status
System.out.println(">>>>>>>>> Updating table >>>>>>>>");
model.addRow(arrayRow); // Add row to table
arrayRow = new String[dataCol.size()];
arrayRow[0] = dataCol.get(2);
arrayRow[1] = dataCol.get(1);
arrayRow[2] = dataCol.get(4);
status = "Ok";
}
}
setAppservName();
} catch (Exception e) {
e.printStackTrace();
}
}
// Get row count
public int getRowCount(){
return model.getRowCount();
}
// Set table data
public void setAppservName(){
Vector data = model.getDataVector();
Vector row = (Vector) data.elementAt(1);
// Copy the first column
int mColIndex = 0;-
colData = new ArrayList(table.getRowCount()+1);
for (int i = 0; i < table.getRowCount(); i++) {
row = (Vector) data.elementAt(i);
colData.add(row.get(mColIndex));
}
}
// Get table data
public String getAppservName(int rowNum){
return (String) colData.get(rowNum);
}
// Set appserver info
public void setAppservInfo(String appservInfo){
textAreaInfo.setText(appservInfo);
textAreaInfo.setCaretPosition(0); // Set cursor at top of text
}
// Get appserver info
public String getAppservInfo(){
return textAreaInfo.getText();
}
/**
* Action listeners
*/
public void addTableRowListener(ListSelectionListener listSelectionEvent) {
table.getSelectionModel().addListSelectionListener(listSelectionEvent);
}
public void addButtonListener(ActionListener buttonEvent) {
btnSaveInfo.addActionListener(buttonEvent);
btnSaveInfo.setActionCommand("saveAppServInfo");
}
}
选择非零行并运行刷新线程时的跟踪输出
** Appserver worker **
CmtModel: readAppservData
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>> Rowcount = 8
选择零行并运行刷新线程时的跟踪输出
** Appserver worker **
CmtModel: readAppservData
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 0 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 1 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 2 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 3 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 4 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 5 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 6 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 7 <<
>>>>>>>>> Updating the table >>>>>>>>
>>>>>>>>> Selection list handler ! >>>>>>>>
>> Controll: selectedRow = 8 <<
java.lang.IndexOutOfBoundsException: Index: 8, Size: 8
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at panels.ExtAppServPanel.getAppservName(ExtAppServPanel.java:219)
at Control$SharedListSelectionHandler.valueChanged(Control.java:330)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.insertIndexInterval(Unknown Source)
at javax.swing.JTable.tableRowsInserted(Unknown Source)
at javax.swing.JTable.tableChanged(Unknown Source)
at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)
at javax.swing.table.AbstractTableModel.fireTableRowsInserted(Unknown Source)
at javax.swing.table.DefaultTableModel.insertRow(Unknown Source)
at javax.swing.table.DefaultTableModel.addRow(Unknown Source)
at javax.swing.table.DefaultTableModel.addRow(Unknown Source)
at panels.ExtAppServPanel.setAppserverData(ExtAppServPanel.java:172)
at Control$AppserverWorker.doInBackground(Control.java:434)
at Control$AppserverWorker.doInBackground(Control.java:1)
at javax.swing.SwingWorker$1.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at javax.swing.SwingWorker.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
最佳答案
// Update GUI
theGui.extAppServPanel.setAppserverData(theModel.getAppservData());
不要在 doInBackground()
方法中更新模型或 GUI。
对 GUI 的所有更新都应在 EventDispatchThread (EDT)
上完成。
相反,当数据更改时,您需要“发布”结果,以便可以在 SwingWorker
的 process(...)
方法中执行代码,该方法在 EDT 上执行,因此 GUI 将在 EDT 上更新。
阅读 Swing 教程中关于 Concurrency 的部分了解更多信息。关于具有中间结果的任务
的部分提供了发布方法的示例。
关于java - 当选择 JTable 中的第 0 行时,选择处理程序会发疯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34003790/
我是一名优秀的程序员,十分优秀!