私は SWING にまったく慣れていないので、いくつかのテストの後、非常に単純なプログラムに CardLayout を使用することにしました。3 つのカード (ログイン用、データ追加用、および表示用) があります。問題は、それらのカード間で共有されている (参照を渡された) リストがあり、複数のカードで変更できることです。何らかの理由で、少し遊んだ後、以下のエラーに見られるように、リストを反復しようとしているときにプログラムが中断します。
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
リストなどを変更する以外にスレッドがないため、例外が発生する理由がわかりません。リストを操作するコードの一部を同期しようとしましたが、良い結果は得られませんでした。私が自分自身を明確にしたかどうか完全にはわかりません。お気軽に質問してください。(コードは単なるスニペットではないため提供されていませんが、必要であると判断した場合は掲載します)。
前もって感謝します。
-- 編集 -- コードは次のとおりです: メイン クラス:
package cantodasletras.br.views;
import java.awt.CardLayout;
public class CantoDasLetrasMain {
private JFrame frmCantodasletras;
private static int DEBUG = 0;
private final String LOGINMENU = "The user login view";
private final String MENUVIEW = "The user menu view";
private final String SEARCHVIEW = "The search view";
private final String ADDNEWVIEW = "The create new order view";
private ArrayList<Order> listOfOrders = null;
private JPanel renderPanel;
/**
* Launch the application.
*/
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
if (args.length > 0)
DEBUG = 1;
try {
CantoDasLetrasMain window = new CantoDasLetrasMain();
window.frmCantodasletras.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public CantoDasLetrasMain() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
listOfOrders = new ArrayList<Order>();
UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
frmCantodasletras = new JFrame();
frmCantodasletras.setTitle("CantoDasLetras 1.0");
frmCantodasletras.setBounds(100, 100, 754, 530);
frmCantodasletras.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmCantodasletras.getContentPane().setLayout(null);
renderPanel = new JPanel();
renderPanel.setBounds(0, 0, 738, 472);
frmCantodasletras.getContentPane().add(renderPanel);
renderPanel.setLayout(new CardLayout(0, 0));
CardLayout cl = (CardLayout) renderPanel.getLayout();
//Inicializar todas as views
LoginView lv = new LoginView(cl,renderPanel);
renderPanel.add(lv, LOGINMENU);
MenuView mv = new MenuView(cl, renderPanel);
renderPanel.add(mv,MENUVIEW);
SearchView sv = new SearchView(cl,renderPanel,listOfOrders);
renderPanel.add(sv,SEARCHVIEW);
AddNewView anv = new AddNewView(cl, renderPanel,listOfOrders);
renderPanel.add(anv,ADDNEWVIEW);
}
}
カードは次のとおりです。
package cantodasletras.br.views;
import java.awt.CardLayout;
public class AddNewView extends JPanel {
private final String MENUVIEW = "The user menu view";
private JTextField fieldNome;
private JTextField fieldTelefone;
private JTextField fieldLivro;
private JTextField fieldQuantidade;
private JTextField fieldData;
private JComboBox cBSit;
private JTextArea fieldObs;
/**
* Create the panel.
*/
public AddNewView(final CardLayout cl, final JPanel renderPanel,
final ArrayList<Order> orders) {
setLayout(null);
JButton btnNewButton = new JButton("Cancelar");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cl.show(renderPanel, MENUVIEW);
}
});
btnNewButton.setBounds(541, 429, 89, 33);
add(btnNewButton);
JButton btnCadastrar = new JButton("Cadastrar");
btnCadastrar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String nome = fieldNome.getText();
String livro = fieldLivro.getText();
String telefone = fieldTelefone.getText();
String situacao = (String) cBSit.getSelectedItem();
Integer quantidade = Integer.parseInt(fieldQuantidade.getText());
String obs = fieldObs.getText();
String data = fieldData.getText();
fieldNome.setText("");
fieldLivro.setText("");
fieldTelefone.setText("");
cBSit.setSelectedIndex(0);
fieldQuantidade.setText("");
fieldObs.setText("");
fieldData.setText("");
orders.add(new Order(nome, data, livro, telefone, situacao, quantidade,
obs));
cl.show(renderPanel, MENUVIEW);
return;
}
});
btnCadastrar.setBounds(424, 429, 89, 33);
add(btnCadastrar);
JLabel lblNome = new JLabel("Nome:");
lblNome.setBounds(44, 64, 46, 14);
add(lblNome);
JLabel lblTelefone = new JLabel("Telefone:");
lblTelefone.setBounds(44, 108, 46, 14);
add(lblTelefone);
JLabel lblLivro = new JLabel("Livro:");
lblLivro.setBounds(44, 150, 46, 14);
add(lblLivro);
fieldNome = new JTextField();
fieldNome.setBounds(108, 61, 498, 20);
add(fieldNome);
fieldNome.setColumns(10);
fieldTelefone = new JTextField();
fieldTelefone.setBounds(108, 105, 498, 20);
add(fieldTelefone);
fieldTelefone.setColumns(10);
fieldLivro = new JTextField();
fieldLivro.setBounds(108, 147, 498, 20);
add(fieldLivro);
fieldLivro.setColumns(10);
JLabel lblSituao = new JLabel("Situa\u00E7\u00E3o:");
lblSituao.setBounds(44, 186, 46, 14);
add(lblSituao);
JLabel lblNewLabel = new JLabel("Quantidade:");
lblNewLabel.setBounds(44, 224, 60, 14);
add(lblNewLabel);
fieldQuantidade = new JTextField();
fieldQuantidade.setBounds(108, 221, 498, 20);
add(fieldQuantidade);
fieldQuantidade.setColumns(10);
JLabel lblObs = new JLabel("Obs:");
lblObs.setBounds(44, 300, 46, 14);
add(lblObs);
JLabel lblCadastroDeNovo = new JLabel("Cadastro de Novo Pedido");
lblCadastroDeNovo.setFont(new Font("Tahoma", Font.PLAIN, 17));
lblCadastroDeNovo.setBounds(253, 21, 190, 20);
add(lblCadastroDeNovo);
cBSit = new JComboBox();
cBSit.setModel(new DefaultComboBoxModel(new String[] { "A pedir",
"Pedido Feito", "Avisado", "ND", "Esgotado", "Fora de Cat\u00E1logo",
"N\u00E3o Encontrado", "Lan\u00E7amento Previsto", "Entregue",
"Desisdente" }));
cBSit.setSelectedIndex(0);
cBSit.setBounds(108, 183, 498, 20);
add(cBSit);
JLabel lblData = new JLabel("Data:");
lblData.setBounds(44, 261, 46, 14);
add(lblData);
fieldData = new JTextField();
fieldData.setBounds(108, 261, 498, 20);
add(fieldData);
fieldData.setColumns(10);
fieldObs = new JTextArea();
fieldObs.setText("Sem obs;");
fieldObs.setBounds(108, 300, 498, 96);
add(fieldObs);
}
}
最後の一つ:
package cantodasletras.br.views;
import java.awt.BorderLayout;
public class SearchView extends JPanel {
private final String MENUVIEW = "The user menu view";
private JTable table;
private JTextField textField_1;
/**
* Create the panel.
*/
public SearchView(final CardLayout cl, final JPanel renderPanel,
final ArrayList<Order> orders) {
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths =
new int[] { 0, 0, 17, 224, 66, 333, 77, 0, 0, 0, 0, 0, 0, 0, 0 };
gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 0, 0, 0 };
gridBagLayout.columnWeights =
new double[] { 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, Double.MIN_VALUE };
gridBagLayout.rowWeights =
new double[] { 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, Double.MIN_VALUE };
setLayout(gridBagLayout);
JLabel lblBuscarCadastro = new JLabel("Buscar Cadastro");
lblBuscarCadastro.setFont(new Font("Tahoma", Font.PLAIN, 17));
GridBagConstraints gbc_lblBuscarCadastro = new GridBagConstraints();
gbc_lblBuscarCadastro.insets = new Insets(0, 0, 5, 5);
gbc_lblBuscarCadastro.gridx = 5;
gbc_lblBuscarCadastro.gridy = 0;
add(lblBuscarCadastro, gbc_lblBuscarCadastro);
JLabel lblFiltro = new JLabel("Filtro:");
GridBagConstraints gbc_lblFiltro = new GridBagConstraints();
gbc_lblFiltro.anchor = GridBagConstraints.SOUTH;
gbc_lblFiltro.insets = new Insets(0, 0, 5, 5);
gbc_lblFiltro.gridx = 3;
gbc_lblFiltro.gridy = 1;
add(lblFiltro, gbc_lblFiltro);
JComboBox comboBox = new JComboBox();
comboBox.setModel(new DefaultComboBoxModel(new String[] { "Nome", "Livro",
"A pedir", "Pedido Feito", "Avisado", "ND", "Esgotado",
"Fora de Cat\u00E1logo", "N\u00E3o Encontrado",
"Lan\u00E7amento Previsto", "Entregue", "Cancelado" }));
GridBagConstraints gbc_comboBox = new GridBagConstraints();
gbc_comboBox.insets = new Insets(0, 0, 5, 5);
gbc_comboBox.gridx = 3;
gbc_comboBox.gridy = 2;
add(comboBox, gbc_comboBox);
textField_1 = new JTextField();
GridBagConstraints gbc_textField_1 = new GridBagConstraints();
gbc_textField_1.insets = new Insets(0, 0, 5, 5);
gbc_textField_1.fill = GridBagConstraints.HORIZONTAL;
gbc_textField_1.gridx = 5;
gbc_textField_1.gridy = 2;
add(textField_1, gbc_textField_1);
textField_1.setColumns(10);
JButton btnProcurar = new JButton("Procurar");
btnProcurar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DefaultTableModel dm = (DefaultTableModel) table.getModel();
dm.setRowCount(0);
initTable(orders);
}
});
GridBagConstraints gbc_btnProcurar = new GridBagConstraints();
gbc_btnProcurar.insets = new Insets(0, 0, 5, 5);
gbc_btnProcurar.gridx = 7;
gbc_btnProcurar.gridy = 2;
add(btnProcurar, gbc_btnProcurar);
JButton btnVoltar = new JButton("Voltar");
btnVoltar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cl.show(renderPanel, MENUVIEW);
}
});
GridBagConstraints gbc_btnVoltar = new GridBagConstraints();
gbc_btnVoltar.insets = new Insets(0, 0, 5, 5);
gbc_btnVoltar.gridx = 9;
gbc_btnVoltar.gridy = 2;
add(btnVoltar, gbc_btnVoltar);
JPanel panel_1 = new JPanel();
GridBagConstraints gbc_panel_1 = new GridBagConstraints();
gbc_panel_1.gridheight = 3;
gbc_panel_1.gridwidth = 9;
gbc_panel_1.insets = new Insets(0, 0, 5, 5);
gbc_panel_1.fill = GridBagConstraints.BOTH;
gbc_panel_1.gridx = 3;
gbc_panel_1.gridy = 3;
add(panel_1, gbc_panel_1);
JComboBox combo = new JComboBox();
combo.setModel(new DefaultComboBoxModel(new String[] { "A pedir",
"Pedido Feito", "Avisado", "ND", "Esgotado", "Fora de Cat\u00E1logo",
"N\u00E3o Encontrado", "Lan\u00E7amento Previsto", "Entregue",
"Desisdente" }));
combo.setSelectedIndex(0);
panel_1.setLayout(new BorderLayout());
table = new JTable();
table
.setModel(new DefaultTableModel(new Object[][] {},
new String[] { "Telefone", "Nome", "Data", "Livro", "Quantidade",
"Situacao", "Obs" }));
table.getColumn(table.getColumnName(5)).setCellEditor(
new javax.swing.DefaultCellEditor(combo));
table.getModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
if (!(table.getModel().getRowCount() > 0))
return;
if (e.getType() == TableModelEvent.UPDATE) {
int col = e.getColumn();
int row = e.getFirstRow();
String telefone = (String) table.getValueAt(row, 0);
String nome = (String) table.getValueAt(row, 1);
String data = (String) table.getValueAt(row, 2);
String livro = (String) table.getValueAt(row, 3);
String quantidade = (String) table.getValueAt(row, 4);
String situacao = ((String) table.getValueAt(row, 5));
String obs = (String) table.getValueAt(row, 6);
Order nOrd =
new Order(nome, data, livro, telefone, situacao, Integer
.parseInt(quantidade), obs);
if (col == 0 || col == 1) {
int result =
JOptionPane
.showConfirmDialog(
(Component) null,
"Alterar o nome ou telefone de um cadastro irá gerar um novo cadastro. Deseja continuar?",
"Alerta!", JOptionPane.OK_CANCEL_OPTION);
if (result == 0) {
if (!orders.contains(nOrd))
orders.add(nOrd);
}
return;
}
for (Order or : orders) {
if (or.equals(nOrd))
orders.remove(or);
orders.add(nOrd);
}
}
}
});
JScrollPane tableContainer = new JScrollPane(table);
panel_1.add(tableContainer, BorderLayout.CENTER);
}
void initTable(ArrayList<Order> orders) {
// Initialize table
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
for (Order order : orders) {
dtm.addRow(new Object[] { order.getTelefone(), order.getNome(),
order.getData(), order.getLivro(), order.getQuantidade().toString(),
order.getSituacao(), order.getObs() });
}
}
}