Java 卡片布局+;并发性

Java 卡片布局+;并发性,java,swing,concurrency,cardlayout,Java,Swing,Concurrency,Cardlayout,我对SWING非常陌生,经过一些测试,我决定使用CardLayout来实现一个非常简单的程序:我有3张卡(一张用于登录,一张用于添加数据,另一张用于显示数据)。 问题是,我有一个列表,在这些卡片之间共享(通过了引用),它可以被多张卡片修改。 出于某种原因,在我玩了一会儿之后,程序在尝试遍历列表时中断,如下面的错误所示: Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException at java.

我对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;
导入java.awt.CardLayout;
公共级康托达斯勒特拉斯曼{
私人JFrame frmCantodasletras;
私有静态int-DEBUG=0;
private final String LOGINMENU=“用户登录视图”;
私有最终字符串MENUVIEW=“用户菜单视图”;
私有最终字符串SEARCHVIEW=“搜索视图”;
私有最终字符串ADDNEWVIEW=“创建新订单视图”;
私有ArrayList listOfOrders=null;
私人JPanel renderPanel;
/**
*启动应用程序。
*/
公共静态void main(最终字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
如果(args.length>0)
调试=1;
试一试{
CantoDasLetrasMain窗口=新的CantoDasLetrasMain();
window.frmCantodasletras.setVisible(true);
}
捕获(例外e){
e、 printStackTrace();
}
}
});
}
/**
*创建应用程序。
*/
公共康托达斯勒特拉斯曼(){
初始化();
}
/**
*初始化框架的内容。
*/
私有void初始化(){
listOfOrders=新的ArrayList();
put(“Button.defaultButtonFollowsFocus”,Boolean.TRUE);
frmCantodasletras=newjframe();
frmCantodasletras.setTitle(“CantoDasLetras 1.0”);
松鸡(100100754530);
frmCantodasletras.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmCantodasletras.getContentPane().setLayout(null);
renderPanel=新的JPanel();
renderPanel.setBounds(0,0738472);
frmCantodasletras.getContentPane().add(renderPanel);
renderPanel.setLayout(新的CardLayout(0,0));
CardLayout cl=(CardLayout)renderPanel.getLayout();
//Inicializar todas作为视图
LoginView lv=新LoginView(cl,renderPanel);
renderPanel.add(lv,LOGINMENU);
MenuView mv=新MenuView(cl,renderPanel);
renderPanel.add(mv,菜单视图);
SearchView sv=新的SearchView(cl、renderPanel、listOfOrders);
renderPanel.add(sv,SEARCHVIEW);
AddNewView anv=新的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;
导入java.awt.CardLayout;
公共类AddNewView扩展了JPanel{
私有最终字符串MENUVIEW=“用户菜单视图”;
私人JTextField fieldNome;
私人JTextField现场电话;
私人JTextField fieldLivro;
专用JTextField字段量化;
私有JTextField字段数据;
私人JComboBox cBSit;
私人JTextArea fieldObs;
/**
*创建面板。
*/
public AddNewView(最终卡片布局cl、最终JPanel renderPanel、,
最终ArrayList订单){
setLayout(空);
JButton btnNewButton=新JButton(“取消”);
addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件e){
cl.show(renderPanel、MENUVIEW);
}
});
btnNewButton.setBounds(541429,89,33);
添加(btnNewButton);
JButton btnCadastrar=新JButton(“地籍”);
btnCadastrar.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件e){
字符串nome=fieldNome.getText();
字符串livro=fieldLivro.getText();
String telefone=fieldTelefone.getText();
String situacao=(String)cBSit.getSelectedItem();
整数quantidade=Integer.parseInt(fieldQuantidade.getText());
字符串obs=fieldObs.getText();
String data=fieldData.getText();
fieldNome.setText(“”);
fieldLivro.setText(“”);
fieldTelefone.setText(“”);
cBSit.setSelectedIndex(0);
fieldQuantidade.setText(“”);
fieldObs.setText(“”);
fieldData.setText(“”);
订单。添加(新订单(nome、data、livro、telefone、situacao、quantidade、,
obs),;
cl.show(renderPanel、MENUVIEW);
返回;
}
});
btnCadastrar.立根(424429,89,33);
添加(btnCadastrar);
JLabel lblNome=新JLabel(“Nome:”);
lblNome.挫折(44,64,46,14);
添加(lblNome);
JLabel lblTelefone=新JLabel(“Telefone:”);
立根(44108,46,14);
添加(lblTelefone);
JLabel lblLivro=新JLabel(“Livro”);
立根(44150,46,14);
添加(lblLivro);
fieldNome=新的JTextField();
立根野名词(108,61,498,20);
添加(fieldNome);
字段名称设置列(10);
fieldTelefone=新的JTextField();
野战电话机(108、105、498、20);
添加(现场电话);
fieldTelefone.setColumns(10);
fieldLivro=新的JTextField();
退步(108147498,20);
添加(fieldLivro);
fieldLivro.setColumns(10);
JLabel lblSituao=新的JLabel(“Situa\u00E7\u00E3o:”);
lblSituao.立根(44,186,46,14);
添加(lblSituao);
JLabel lblNewLabel=新JLabel(“量化数据:”);
lblNewLabel.立根(44224,60,14);
添加(lblNewLabel);
fieldQuantidade=新的JTextField();
退步数(108221498,20);
添加(字段量化);
fieldQuantidade.setColumns(10);
JLabel lblObs=新的JLabel(“Obs:”);
lblObs.挫折(44300,46,14);
添加(lblObs);
JLabel lblCada
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() });

    }

  }
}
  for (Order or : orders) {
    if (or.equals(nOrd))
      orders.remove(or);
  }
for (Iterator<Order> iterator = orders.iterator(); iterator.hasNext();) {
    Order order = iterator.next();
    if (order.equals(nOrd)) {
        iterator.remove();
    }
}