Java 抽象表模型 : getValueAt does not use updated data

标签 java swing abstracttablemodel

我有一个带有四个卡片面板的 Java 应用程序。在第一个面板中,我接收第一个地理点的数据,在第二个和第三个地理点中接收其他两个点的数据,在第四个面板中,我有一个 JTable 显示有关这三个点的提取信息。

以下代码可用于编译该应用程序。在每个卡片面板上,尝试单击 JTextfield 旁边的按钮来添加数据。

封装模型

类AppSingleton

public class AppSingleton 
{
  private static AppSingleton instance = null;  

  public List<List<String>> flightPlanShared = new ArrayList<List<String>>(){{
    add(Arrays.asList(""));
    add(Arrays.asList(""));
    add(Arrays.asList(""));
  }};

  private AppSingleton() 
  {

  }

  public static AppSingleton getInstance() 
  {
    if(instance == null) 
    {
        instance = new AppSingleton();
    }
    return instance;
  }
}

类 Model_Flightplan

import java.util.ArrayList;
import java.util.List;
import presenters.Presenter;
import views.View_MainFrame;

public class Model_Flightplan 
{
    AppSingleton appSingleton = AppSingleton.getInstance( );
    private Presenter presenter;
    private View_MainFrame viewMainFrame; 

    public Model_Flightplan(View_MainFrame viewMainFrame) 
    {
       this.viewMainFrame = viewMainFrame;
    }

    public Presenter getPresenter() {
        return presenter;
    }

    public void setPresenter(Presenter presenter) {
       this.presenter = presenter;
    }

    public void addDepartureAirport() 
    {          
      List<String> component = new ArrayList<>();
      component.add("KLAS");
      component.add("KLAS");
      component.add("KLAS");

      appSingleton.flightPlanShared.set(0, component);
    }                                         

    public void addDestinationAirport()
    {
      List<String> component = new ArrayList<>();
      component.add("KLAX");
      component.add("KLAX");
      component.add("KLAX");

      appSingleton.flightPlanShared.set( (appSingleton.flightPlanShared.size() - 2), component);
    }

    public void addAlternateAirport()
    {
      List<String> component = new ArrayList<>();
      component.add("KSEA");
      component.add("KSEA");
      component.add("KSEA");

      appSingleton.flightPlanShared.set( (appSingleton.flightPlanShared.size() - 1), component);
     }  
 }

类模型_TableWindsAloft

package models;

import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class Model_TableWindsAloft extends AbstractTableModel
{

    String[] columnNames = {"ICAO","Name","Type"};

    private List<List<String>> tableData = new ArrayList<>();

    public Model_TableWindsAloft(List<List<String>> tableData)
    {
       this.tableData = tableData;
       System.out.println("CONSTRUCTOR? "+tableData);
    }


    @Override
    public int getRowCount() 
    {
        System.out.println("DATA COUNT? "+tableData.size());
       return(tableData.size());
    }

    @Override
    public int getColumnCount() {
       return(columnNames.length);
    }

    @Override
    public String getColumnName(int column) 
    {
       return columnNames[column] ;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) 
    {
      System.out.println("WHAT IS DATA 1? "+tableData);

      List<String> data = tableData.get(rowIndex);

      System.out.println("WHAT IS DATA 2? "+data);

      if(data.size()>=3)
      {
        switch(columnIndex) 
        {
            case 0: 
                return data.get(0);
            case 1:
                return data.get(1);
            case 2:
                return data.get(2);
            default: 
                return null;
         }
       }
       else
       {
          return null;
       }
    }
 }

包装演示者

类主持人

package presenters;

import java.awt.CardLayout;
import models.Model_Flightplan;
import views.View_MainFrame;

public class Presenter 
{
  private final View_MainFrame viewMainFrame;
  private final Model_Flightplan model;

  public Presenter(View_MainFrame viewMainFrame, Model_Flightplan model) 
  {
    this.viewMainFrame = viewMainFrame;
    this.model = model;
  }

  public void displayTabDep() 
  {            
    CardLayout card = (CardLayout)viewMainFrame.getPanelContext().getLayout();
    card.show(viewMainFrame.getPanelContext(), "cardDep");
    viewMainFrame.addButtonsFlightplan();
    viewMainFrame.btnPnlDeparture.setEnabled(false);
  }

  public void displayTabDest() 
  {
    CardLayout card = (CardLayout)viewMainFrame.getPanelContext().getLayout();
    card.show(viewMainFrame.getPanelContext(), "cardDest");
    viewMainFrame.addButtonsFlightplan();
    viewMainFrame.btnPnlDestination.setEnabled(false);
  }

  public void displayTabAlt() 
  {
    CardLayout card = (CardLayout)viewMainFrame.getPanelContext().getLayout();
    card.show(viewMainFrame.getPanelContext(), "cardAlt");
    viewMainFrame.addButtonsFlightplan();
    viewMainFrame.btnPnlAlternate.setEnabled(false);
  }

  public void displayTabWindsAloft() 
  {
    CardLayout card = (CardLayout)viewMainFrame.getPanelContext().getLayout();
    card.show(viewMainFrame.getPanelContext(), "cardWindsAloft");

    viewMainFrame.addButtonsFlightplan();
    viewMainFrame.btnPnlWindsAloft.setEnabled(false);

    viewMainFrame.createPanelWindsAloft();
  }

  public void addDeparture()
  {
    model.addDepartureAirport();
  }

  public void addDestination()
  {
    model.addDestinationAirport();
  }

  public void addAlternate()
  {
    model.addAlternateAirport();
  }
}

包 View

类View_MainFrame

package views;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import models.AppSingleton;
import presenters.Presenter;

public class View_MainFrame 
{
  AppSingleton appSingleton = AppSingleton.getInstance( );
  private Presenter presenter;
  private JPanel panelContext;

  private JFrame frame;

  public JPanel pnlDep;
  public JPanel pnlDest;
  public JPanel pnlAlt;
  public JPanel pnlWindsAloft;
  public JPanel panelButtons;
  public JButton btnFlightplan;
  public JPanel panelButtonsAdd;
  public JButton btnFlightplanDummy;
  public JPanel pnlDepAirport;
  private JButton btnAddDep;

  private javax.swing.JPanel pnlDestAirport;
  public JButton btnAddDest;

  private javax.swing.JPanel pnlAltAirport;
  public JButton btnAddAlt;

  private javax.swing.JPanel pnlWindsAloftInfo;
  private javax.swing.JPanel pnlWindsAloftTable;
  public JButton btnPnlDeparture;
  public JButton btnPnlDestination;
  public JButton btnPnlAlternate;
  public JButton btnPnlWindsAloft;

  public View_MainFrame()
  {
    createUI();
  }

  private void createUI() 
  {
    JFrame.setDefaultLookAndFeelDecorated(true);
    frame = new JFrame("iGoDispatch IXEG Boeing-733");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(new javax.swing.BoxLayout(frame.getContentPane(), javax.swing.BoxLayout.Y_AXIS));

    Dimension frameSize = new Dimension(1050,700);
    Dimension frameSizeMin = new Dimension(500,200);
    frame.setPreferredSize(frameSize);
    frame.setMinimumSize(frameSizeMin);

    createPanelButtons();
    createPanelButtonsAdd();
    createPanelDeparture();
    createPanelDestination();
    createPanelAlternate();
    pnlWindsAloft = new JPanel();
    pnlWindsAloft.setLayout(new java.awt.BorderLayout());
    createPanelWindsAloft();

    setPanelContext(new JPanel());
    getPanelContext().setLayout(new java.awt.CardLayout());
    frame.getContentPane().add(getPanelContext(), java.awt.BorderLayout.SOUTH);

    getPanelContext().add(pnlDep, "cardDep");
    getPanelContext().add(pnlDest, "cardDest");
    getPanelContext().add(pnlAlt, "cardAlt");
    getPanelContext().add(pnlWindsAloft, "cardWindsAloft");

    frame.pack();
    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
  }

  public JPanel getPanelContext() {
    return panelContext;
  }

  public void setPanelContext(JPanel panelContext) {
    this.panelContext = panelContext;
  }

  private void createPanelButtons()
  {
    panelButtons = new JPanel();
    panelButtons.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
    panelButtons.setLayout(new java.awt.GridLayout(1, 0));
    Dimension panelButtonsMinSize = new Dimension(1050,60);
    panelButtons.setMinimumSize(panelButtonsMinSize);

    btnFlightplan = new JButton();
    btnFlightplan.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
    btnFlightplan.setText("Flightplan");
    btnFlightplan.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    btnFlightplan.setIconTextGap(5);
    btnFlightplan.setMaximumSize(new java.awt.Dimension(70, 70));
    btnFlightplan.setMinimumSize(new java.awt.Dimension(70, 70));
    btnFlightplan.setPreferredSize(new java.awt.Dimension(70, 70));
    btnFlightplan.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    btnFlightplan.addActionListener((java.awt.event.ActionEvent evt) -> 
    {
        getPresenter().displayTabDep();
    });
    panelButtons.add(btnFlightplan);

    frame.getContentPane().add(panelButtons, java.awt.BorderLayout.NORTH);
  }

  private void createPanelButtonsAdd()
  {
    panelButtonsAdd = new JPanel();
    panelButtonsAdd.setBorder(javax.swing.BorderFactory.createEtchedBorder());
    frame.getContentPane().add(panelButtonsAdd, java.awt.BorderLayout.CENTER);
    panelButtonsAdd.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

    // Dummy button
    btnFlightplanDummy = new JButton();
    btnFlightplanDummy.setAlignmentY(0.0F);
    btnFlightplanDummy.setEnabled(false);
    btnFlightplanDummy.setVisible(false);
    btnFlightplanDummy.setMaximumSize(new java.awt.Dimension(50, 50));
    btnFlightplanDummy.setMinimumSize(new java.awt.Dimension(50, 50));
    btnFlightplanDummy.setPreferredSize(new java.awt.Dimension(50, 50));
    panelButtonsAdd.add(btnFlightplanDummy);

    addButtonsFlightplan();
  }

  public void addButtonsFlightplan()
  {
    removeButtons();
    Dimension buttonDim = new Dimension(50, 50);
    Font buttonFont = new Font("Helvetica", Font.PLAIN, 10);
    btnPnlDeparture = new JButton("DEP");
    btnPnlDeparture.setPreferredSize(buttonDim);
    btnPnlDeparture.setFont(buttonFont);
    btnPnlDeparture.setVisible(true);
    btnPnlDeparture.addActionListener((ActionEvent e) -> 
    {
        getPresenter().displayTabDep();
    }); 

    panelButtonsAdd.add(btnPnlDeparture);

    btnPnlDestination = new JButton("ARR");
    btnPnlDestination.setPreferredSize(buttonDim);
    btnPnlDestination.setFont(buttonFont);
    btnPnlDestination.setVisible(true);
    btnPnlDestination.addActionListener((ActionEvent e) -> 
    {
        getPresenter().displayTabDest();
    });
    panelButtonsAdd.add(btnPnlDestination);

    btnPnlAlternate = new JButton("ALT");
    btnPnlAlternate.setPreferredSize(buttonDim);
    btnPnlAlternate.setFont(buttonFont);
    btnPnlAlternate.setVisible(true);
    btnPnlAlternate.addActionListener((ActionEvent e) -> 
    {
        getPresenter().displayTabAlt();
    });
    panelButtonsAdd.add(btnPnlAlternate);

    btnPnlWindsAloft = new JButton("WINDS");
    btnPnlWindsAloft.setPreferredSize(buttonDim);
    btnPnlWindsAloft.setFont(buttonFont);
    btnPnlWindsAloft.setVisible(true);
    btnPnlWindsAloft.addActionListener((ActionEvent e) -> 
    {
        getPresenter().displayTabWindsAloft();
    });
    panelButtonsAdd.add(btnPnlWindsAloft);

    panelButtonsAdd.revalidate();
    panelButtonsAdd.repaint();
  }


  private void removeButtons()
  {
    panelButtonsAdd.removeAll();
    panelButtonsAdd.revalidate();
    panelButtonsAdd.repaint();
  }

  private void createPanelDeparture()
  {
    java.awt.GridBagConstraints gridBagConstraints;

    pnlDep = new JPanel();
    pnlDep.setLayout(new java.awt.BorderLayout());

    pnlDepAirport = new JPanel();
    pnlDepAirport.setLayout(new java.awt.GridBagLayout());

    btnAddDep = new JButton();
    btnAddDep.setText("ADD");
    btnAddDep.setMaximumSize(new java.awt.Dimension(35, 35));
    btnAddDep.setMinimumSize(new java.awt.Dimension(35, 35));
    btnAddDep.setPreferredSize(new java.awt.Dimension(35, 35));
    btnAddDep.addActionListener((java.awt.event.ActionEvent evt) -> 
    {
        JFrame f = new JFrame(); 
        JDialog modalDialog = new JDialog(f, "Busy", Dialog.ModalityType.MODELESS);
        modalDialog.setSize(200, 100);
        modalDialog.setLocationRelativeTo(f);
        modalDialog.setUndecorated(true);
        // Remove menu buttons
        modalDialog.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
        modalDialog.getContentPane().setBackground( Color.WHITE );
        // Add rotating activity indicator
        ImageIcon loading = new ImageIcon("src/images/activityIndicator.gif");
        modalDialog.add(new JLabel("Please wait... ", loading, JLabel.CENTER));
        // Set activity indicator visible
        modalDialog.setVisible(true);

        new Thread(() ->
        {
            getPresenter().addDeparture(); 
            SwingUtilities.invokeLater(() ->
            {
                modalDialog.setVisible(false);
                modalDialog.dispose();
            });
        }).start();
    });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 5);
    pnlDepAirport.add(btnAddDep, gridBagConstraints);

    pnlDep.add(pnlDepAirport);
  }

  private void createPanelDestination()
  {
    java.awt.GridBagConstraints gridBagConstraints;

    pnlDest = new JPanel();
    pnlDest.setLayout(new java.awt.BorderLayout());

    pnlDestAirport = new javax.swing.JPanel();
    pnlDestAirport.setLayout(new java.awt.GridBagLayout());

    btnAddDest = new javax.swing.JButton();
    btnAddDest.setText("jButton1");
    btnAddDest.setMaximumSize(new java.awt.Dimension(35, 35));
    btnAddDest.setMinimumSize(new java.awt.Dimension(35, 35));
    btnAddDest.setPreferredSize(new java.awt.Dimension(35, 35));
    btnAddDest.addActionListener((java.awt.event.ActionEvent evt) -> 
    {
        JFrame f = new JFrame(); 
        JDialog modalDialog = new JDialog(f, "Busy", Dialog.ModalityType.MODELESS);
        modalDialog.setSize(200, 100);
        modalDialog.setLocationRelativeTo(f);
        modalDialog.setUndecorated(true);
        // Remove menu buttons
        modalDialog.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
        modalDialog.getContentPane().setBackground( Color.WHITE );
        // Add rotating activity indicator
        ImageIcon loading = new ImageIcon("src/images/activityIndicator.gif");
        modalDialog.add(new JLabel("Please wait... ", loading, JLabel.CENTER));
        // Set activity indicator visible
        modalDialog.setVisible(true);

        new Thread(() ->
        {
            getPresenter().addDestination(); 
            SwingUtilities.invokeLater(() ->
            {
                //displayValues();

                modalDialog.setVisible(false);
                modalDialog.dispose();

            });
        }).start();
    });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 5);
    pnlDestAirport.add(btnAddDest, gridBagConstraints);

    pnlDest.add(pnlDestAirport);
  }

  private void createPanelAlternate()
  {
    java.awt.GridBagConstraints gridBagConstraints;

    pnlAlt = new JPanel();
    pnlAlt.setLayout(new java.awt.BorderLayout());

    pnlAltAirport = new JPanel();
    pnlAltAirport.setLayout(new java.awt.GridBagLayout());

    btnAddAlt = new JButton();
    btnAddAlt.setText("ADD");
    btnAddAlt.setMaximumSize(new java.awt.Dimension(35, 35));
    btnAddAlt.setMinimumSize(new java.awt.Dimension(35, 35));
    btnAddAlt.setPreferredSize(new java.awt.Dimension(35, 35));
    btnAddAlt.addActionListener((java.awt.event.ActionEvent evt) -> 
    {
        JFrame f = new JFrame(); 
        JDialog modalDialog = new JDialog(f, "Busy", Dialog.ModalityType.MODELESS);
        modalDialog.setSize(200, 100);
        modalDialog.setLocationRelativeTo(f);
        modalDialog.setUndecorated(true);
        // Remove menu buttons
        modalDialog.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
        modalDialog.getContentPane().setBackground( Color.WHITE );
        // Add rotating activity indicator
        ImageIcon loading = new ImageIcon("src/images/activityIndicator.gif");
        modalDialog.add(new JLabel("Please wait... ", loading, JLabel.CENTER));
        // Set activity indicator visible
        modalDialog.setVisible(true);

        new Thread(() ->
        {
            getPresenter().addAlternate(); 
            SwingUtilities.invokeLater(() ->
            {
                modalDialog.setVisible(false);
                modalDialog.dispose();
            });
        }).start();
    });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 5);
    pnlAltAirport.add(btnAddAlt, gridBagConstraints);

    pnlAlt.add(pnlAltAirport);
  }

  public void createPanelWindsAloft()
  {
    pnlWindsAloftInfo = new javax.swing.JPanel();
    pnlWindsAloftInfo.setLayout(new java.awt.GridLayout(1, 0));

    pnlWindsAloftTable = new javax.swing.JPanel();
    pnlWindsAloftTable.setLayout(new BorderLayout());

    javax.swing.JTable tblWindsAloft = new javax.swing.JTable(new Model_TableWindsAloft(createDataForWindsTable()));

    JScrollPane scrollWindsAloft = new JScrollPane(tblWindsAloft,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    tblWindsAloft.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    tblWindsAloft.setFillsViewportHeight(true);
    pnlWindsAloftTable.add(scrollWindsAloft, BorderLayout.CENTER); 

    pnlWindsAloftInfo.add(pnlWindsAloftTable);
    pnlWindsAloft.add(pnlWindsAloftInfo, java.awt.BorderLayout.CENTER);
  }

  public List<List<String>> createDataForWindsTable()
  {
    List<List<String>> finalResult = new ArrayList<>();

    System.out.println("SIZE: "+finalResult.size());

    for (int i=0; i<appSingleton.flightPlanShared.size(); i++)
    {    
        String icao;
        String name;
        String type;

        if(appSingleton.flightPlanShared.get(i).size()>2)
        {
            icao = appSingleton.flightPlanShared.get(i).get(2);
            name = appSingleton.flightPlanShared.get(i).get(1);
            type = appSingleton.flightPlanShared.get(i).get(0);
        }
        else
        {
            icao = "";
            name = "";
            type = "";
        }

            List<String> components = new ArrayList<>();

            components.add(icao);
            components.add(name);
            components.add(type);

            System.out.println("COMPONENTS: "+components);

            finalResult.add(components);
    }

    /* THIS WORKS!
    String a1 = "LAS VEGAS/MC CARRAN ";
    String a2 = "KLAS";
    String a3 = "PORTDEP";

    List<String> a = new ArrayList<>();
    a.add(a1);
    a.add(a2);
    a.add(a3);

    String b1 = "LOS ANGELES INTL";
    String b2 = "KLAX";
    String b3 = "PORTDEST";
    List<String> b = new ArrayList<>();
    b.add(b1);
    b.add(b2);
    b.add(b3);

    String c1 = "SEATTLE-TACOMA INTL";
    String c2 = "KSEA";
    String c3 = "PORTALT";
    List<String> c = new ArrayList<>();
    c.add(c1);
    c.add(c2);
    c.add(c3);

    finalResult.add(a);
    finalResult.add(b);
    finalResult.add(c);
    */

    System.out.println("DATA CREATED: "+finalResult);

    return finalResult;
  }

  public Presenter getPresenter() {
    return presenter;
  }

  public void setPresenter(Presenter presenter) {
    this.presenter = presenter;
  }
}

主要

package testjtable;

import javax.swing.SwingUtilities;
import models.Model_Flightplan;
import presenters.Presenter;
import views.View_MainFrame;

public class TestJTable {

  public static void main(String[] args) 
  {
    SwingUtilities.invokeLater(() -> 
    {
        View_MainFrame viewMainFrame = new View_MainFrame();
        viewMainFrame.setPresenter(new Presenter(viewMainFrame, new Model_Flightplan(viewMainFrame)));
    });
  }
}

数据不会出现在表格内,除非(!!!)我在应用程序外部单击。

编辑:

我通过使用 setValueAt() 方法更新模型解决了该问题:

@Override
public void setValueAt(Object value, int row, int col) 
{
    setTableData(appSingleton.flightPlanShared);
    fireTableCellUpdated(row, col);     
}

最佳答案

您似乎正在创建一个新的 JTable 和一个容纳它的新 JPanel,每次按下“create Winds aloft”按钮。

这是您的 btnPnlWindsAloft JButton 的 ActionListener:

btnPnlWindsAloft.addActionListener((ActionEvent e) -> {
    getPresenter().displayTabWindsAloft();
});

请注意,它调用了 getPresenter().displayTabWindsAloft();,即:

public void displayTabWindsAloft() {
    CardLayout card = (CardLayout) viewMainFrame.getPanelContext().getLayout();
    card.show(viewMainFrame.getPanelContext(), "cardWindsAloft");

    viewMainFrame.addButtonsFlightplan();
    viewMainFrame.btnPnlWindsAloft.setEnabled(false);

    viewMainFrame.createPanelWindsAloft();
}

请注意,此方法调用 viewMainFrame.createPanelWindsAloft();,即:

public void createPanelWindsAloft() {
    pnlWindsAloftInfo = new javax.swing.JPanel();
    pnlWindsAloftInfo.setLayout(new java.awt.GridLayout(1, 0));

    pnlWindsAloftTable = new javax.swing.JPanel();
    pnlWindsAloftTable.setLayout(new BorderLayout());

    javax.swing.JTable tblWindsAloft = new javax.swing.JTable(
            new Model_TableWindsAloft(createDataForWindsTable()));

    JScrollPane scrollWindsAloft = new JScrollPane(tblWindsAloft,
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    tblWindsAloft.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    tblWindsAloft.setFillsViewportHeight(true);
    pnlWindsAloftTable.add(scrollWindsAloft, BorderLayout.CENTER);

    pnlWindsAloftInfo.add(pnlWindsAloftTable);
    pnlWindsAloft.add(pnlWindsAloftInfo, java.awt.BorderLayout.CENTER);
}

...每次调用此方法时,它都会通过调用 createDataForWindsTable()< 创建一个新的 pnlWindsAloftInfo JPanel、一个新的 pnlWindsAloftTable JPanel、一个新的 tblWindsAloft JTable,并用新的表格模型填充该 JTable/。再说一遍,为什么要不必要地重新创建这些组件和模型?

不要这样做——只创建一次关键组件,然后在程序运行时更改 JTable 模型的状态以及保存 JTable 的“卡”JPanel 的可见性状态,但不要继续重新创建 JTable 和模型,其中有些保存数据,有些则不保存。

此外,您的程序的复杂性不必要地巨大,这可能会阻止您发现问题 - 重构并简单地一切

附带问题:您设置关键组件的大小几乎保证它们不会在大多数系统上正确显示(例如我的系统,其中按钮文本显示为 ...)。您也会想避免这种情况。

<小时/>

我当前代码的 MCVE:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;

public class TestJTable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            View_MainFrame viewMainFrame = new View_MainFrame();
            viewMainFrame.setPresenter(
                    new Presenter(viewMainFrame, new Model_Flightplan(viewMainFrame)));
        });
    }
}

class View_MainFrame {
    AppSingleton appSingleton = AppSingleton.getInstance();
    private Presenter presenter;
    private JPanel panelContext;

    private JFrame frame;

    public JPanel pnlDep;
    public JPanel pnlDest;
    public JPanel pnlAlt;
    public JPanel pnlWindsAloft;
    public JPanel panelButtons;
    public JButton btnFlightplan;
    public JPanel panelButtonsAdd;
    public JButton btnFlightplanDummy;
    public JPanel pnlDepAirport;
    private JButton btnAddDep;

    private javax.swing.JPanel pnlDestAirport;
    public JButton btnAddDest;

    private javax.swing.JPanel pnlAltAirport;
    public JButton btnAddAlt;

    private javax.swing.JPanel pnlWindsAloftInfo;
    private javax.swing.JPanel pnlWindsAloftTable;
    public JButton btnPnlDeparture;
    public JButton btnPnlDestination;
    public JButton btnPnlAlternate;
    public JButton btnPnlWindsAloft;

    public View_MainFrame() {
        createUI();
    }

    private void createUI() {
        JFrame.setDefaultLookAndFeelDecorated(true);
        frame = new JFrame("iGoDispatch IXEG Boeing-733");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(
                new javax.swing.BoxLayout(frame.getContentPane(), javax.swing.BoxLayout.Y_AXIS));

        Dimension frameSize = new Dimension(1050, 700);
        Dimension frameSizeMin = new Dimension(500, 200);
        frame.setPreferredSize(frameSize);
        frame.setMinimumSize(frameSizeMin);

        createPanelButtons();
        createPanelButtonsAdd();
        createPanelDeparture();
        createPanelDestination();
        createPanelAlternate();
        pnlWindsAloft = new JPanel();
        pnlWindsAloft.setLayout(new java.awt.BorderLayout());
        createPanelWindsAloft();

        setPanelContext(new JPanel());
        getPanelContext().setLayout(new java.awt.CardLayout());
        frame.getContentPane().add(getPanelContext(), java.awt.BorderLayout.SOUTH);

        getPanelContext().add(pnlDep, "cardDep");
        getPanelContext().add(pnlDest, "cardDest");
        getPanelContext().add(pnlAlt, "cardAlt");
        getPanelContext().add(pnlWindsAloft, "cardWindsAloft");

        frame.pack();
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }

    public JPanel getPanelContext() {
        return panelContext;
    }

    public void setPanelContext(JPanel panelContext) {
        this.panelContext = panelContext;
    }

    private void createPanelButtons() {
        panelButtons = new JPanel();
        panelButtons.setBorder(
                new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        panelButtons.setLayout(new java.awt.GridLayout(1, 0));
        Dimension panelButtonsMinSize = new Dimension(1050, 60);
        panelButtons.setMinimumSize(panelButtonsMinSize);

        btnFlightplan = new JButton();
        btnFlightplan.setFont(new java.awt.Font("Lucida Grande", 1, 13));
        btnFlightplan.setText("Flightplan");
        btnFlightplan.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnFlightplan.setIconTextGap(5);
        btnFlightplan.setMaximumSize(new java.awt.Dimension(90, 70));
        btnFlightplan.setMinimumSize(new java.awt.Dimension(90, 70));
        btnFlightplan.setPreferredSize(new java.awt.Dimension(90, 70));
        btnFlightplan.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnFlightplan.addActionListener((java.awt.event.ActionEvent evt) -> {
            getPresenter().displayTabDep();
        });
        panelButtons.add(btnFlightplan);

        frame.getContentPane().add(panelButtons, java.awt.BorderLayout.NORTH);
    }

    private void createPanelButtonsAdd() {
        panelButtonsAdd = new JPanel();
        panelButtonsAdd.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        frame.getContentPane().add(panelButtonsAdd, java.awt.BorderLayout.CENTER);
        panelButtonsAdd.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
        btnFlightplanDummy = new JButton();
        btnFlightplanDummy.setAlignmentY(0.0F);
        btnFlightplanDummy.setEnabled(false);
        btnFlightplanDummy.setVisible(false);
        btnFlightplanDummy.setMaximumSize(new java.awt.Dimension(50, 50));
        btnFlightplanDummy.setMinimumSize(new java.awt.Dimension(50, 50));
        btnFlightplanDummy.setPreferredSize(new java.awt.Dimension(50, 50));
        panelButtonsAdd.add(btnFlightplanDummy);

        addButtonsFlightplan();
    }

    public void addButtonsFlightplan() {
        removeButtons();
        Dimension buttonDim = new Dimension(150, 50);
        Font buttonFont = new Font("Helvetica", Font.PLAIN, 10);
        btnPnlDeparture = new JButton("DEP");
        btnPnlDeparture.setPreferredSize(buttonDim);
        btnPnlDeparture.setFont(buttonFont);
        btnPnlDeparture.setVisible(true);
        btnPnlDeparture.addActionListener((ActionEvent e) -> {
            getPresenter().displayTabDep();
        });

        panelButtonsAdd.add(btnPnlDeparture);

        btnPnlDestination = new JButton("ARR");
        btnPnlDestination.setPreferredSize(buttonDim);
        btnPnlDestination.setFont(buttonFont);
        btnPnlDestination.setVisible(true);
        btnPnlDestination.addActionListener((ActionEvent e) -> {
            getPresenter().displayTabDest();
        });
        panelButtonsAdd.add(btnPnlDestination);

        btnPnlAlternate = new JButton("ALT");
        btnPnlAlternate.setPreferredSize(buttonDim);
        btnPnlAlternate.setFont(buttonFont);
        btnPnlAlternate.setVisible(true);
        btnPnlAlternate.addActionListener((ActionEvent e) -> {
            getPresenter().displayTabAlt();
        });
        panelButtonsAdd.add(btnPnlAlternate);

        btnPnlWindsAloft = new JButton("WINDS");
        btnPnlWindsAloft.setPreferredSize(buttonDim);
        btnPnlWindsAloft.setFont(buttonFont);
        btnPnlWindsAloft.setVisible(true);
        btnPnlWindsAloft.addActionListener((ActionEvent e) -> {
            getPresenter().displayTabWindsAloft();
        });
        panelButtonsAdd.add(btnPnlWindsAloft);

        panelButtonsAdd.revalidate();
        panelButtonsAdd.repaint();
    }

    private void removeButtons() {
        panelButtonsAdd.removeAll();
        panelButtonsAdd.revalidate();
        panelButtonsAdd.repaint();
    }

    private void createPanelDeparture() {
        java.awt.GridBagConstraints gridBagConstraints;

        pnlDep = new JPanel();
        pnlDep.setLayout(new java.awt.BorderLayout());

        pnlDepAirport = new JPanel();
        pnlDepAirport.setLayout(new java.awt.GridBagLayout());

        btnAddDep = new JButton();
        btnAddDep.setText("ADD");
        btnAddDep.setMaximumSize(new java.awt.Dimension(75, 35));
        btnAddDep.setMinimumSize(new java.awt.Dimension(75, 35));
        btnAddDep.setPreferredSize(new java.awt.Dimension(75, 35));
        btnAddDep.addActionListener((java.awt.event.ActionEvent evt) -> {
            JFrame f = new JFrame();
            JDialog modalDialog = new JDialog(f, "Busy", Dialog.ModalityType.MODELESS);
            modalDialog.setSize(200, 100);
            modalDialog.setLocationRelativeTo(f);
            modalDialog.setUndecorated(true);
            modalDialog.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
            modalDialog.getContentPane().setBackground(Color.WHITE);
            modalDialog.add(new JLabel("Please wait... ", JLabel.CENTER));
            modalDialog.setVisible(true);

            new Thread(() -> {
                getPresenter().addDeparture();
                SwingUtilities.invokeLater(() -> {
                    modalDialog.setVisible(false);
                    modalDialog.dispose();
                });
            }).start();
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 5);
        pnlDepAirport.add(btnAddDep, gridBagConstraints);

        pnlDep.add(pnlDepAirport);
    }

    private void createPanelDestination() {
        java.awt.GridBagConstraints gridBagConstraints;

        pnlDest = new JPanel();
        pnlDest.setLayout(new java.awt.BorderLayout());

        pnlDestAirport = new javax.swing.JPanel();
        pnlDestAirport.setLayout(new java.awt.GridBagLayout());

        btnAddDest = new javax.swing.JButton();
        btnAddDest.setText("jButton1");
        btnAddDest.setMaximumSize(new java.awt.Dimension(75, 35));
        btnAddDest.setMinimumSize(new java.awt.Dimension(75, 35));
        btnAddDest.setPreferredSize(new java.awt.Dimension(75, 35));
        btnAddDest.addActionListener((java.awt.event.ActionEvent evt) -> {
            JFrame f = new JFrame();
            JDialog modalDialog = new JDialog(f, "Busy", Dialog.ModalityType.MODELESS);
            modalDialog.setSize(200, 100);
            modalDialog.setLocationRelativeTo(f);
            modalDialog.setUndecorated(true);
            modalDialog.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
            modalDialog.getContentPane().setBackground(Color.WHITE);
            modalDialog.add(new JLabel("Please wait... ", JLabel.CENTER));
            modalDialog.setVisible(true);

            new Thread(() -> {
                getPresenter().addDestination();
                SwingUtilities.invokeLater(() -> {

                    modalDialog.setVisible(false);
                    modalDialog.dispose();

                });
            }).start();
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 5);
        pnlDestAirport.add(btnAddDest, gridBagConstraints);

        pnlDest.add(pnlDestAirport);
    }

    private void createPanelAlternate() {
        java.awt.GridBagConstraints gridBagConstraints;

        pnlAlt = new JPanel();
        pnlAlt.setLayout(new java.awt.BorderLayout());

        pnlAltAirport = new JPanel();
        pnlAltAirport.setLayout(new java.awt.GridBagLayout());

        btnAddAlt = new JButton();
        btnAddAlt.setText("ADD");
        btnAddAlt.setMaximumSize(new java.awt.Dimension(75, 35));
        btnAddAlt.setMinimumSize(new java.awt.Dimension(75, 35));
        btnAddAlt.setPreferredSize(new java.awt.Dimension(75, 35));
        btnAddAlt.addActionListener((java.awt.event.ActionEvent evt) -> {
            JFrame f = new JFrame();
            JDialog modalDialog = new JDialog(f, "Busy", Dialog.ModalityType.MODELESS);
            modalDialog.setSize(200, 100);
            modalDialog.setLocationRelativeTo(f);
            modalDialog.setUndecorated(true);
            modalDialog.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
            modalDialog.getContentPane().setBackground(Color.WHITE);
            modalDialog.add(new JLabel("Please wait... ", JLabel.CENTER));
            modalDialog.setVisible(true);

            new Thread(() -> {
                getPresenter().addAlternate();
                SwingUtilities.invokeLater(() -> {
                    modalDialog.setVisible(false);
                    modalDialog.dispose();
                });
            }).start();
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 5);
        pnlAltAirport.add(btnAddAlt, gridBagConstraints);

        pnlAlt.add(pnlAltAirport);
    }

    public void createPanelWindsAloft() {
        pnlWindsAloftInfo = new javax.swing.JPanel();
        pnlWindsAloftInfo.setLayout(new java.awt.GridLayout(1, 0));

        pnlWindsAloftTable = new javax.swing.JPanel();
        pnlWindsAloftTable.setLayout(new BorderLayout());

        javax.swing.JTable tblWindsAloft = new javax.swing.JTable(
                new Model_TableWindsAloft(createDataForWindsTable()));

        JScrollPane scrollWindsAloft = new JScrollPane(tblWindsAloft,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        tblWindsAloft.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        tblWindsAloft.setFillsViewportHeight(true);
        pnlWindsAloftTable.add(scrollWindsAloft, BorderLayout.CENTER);

        pnlWindsAloftInfo.add(pnlWindsAloftTable);
        pnlWindsAloft.add(pnlWindsAloftInfo, java.awt.BorderLayout.CENTER);
    }

    public List<List<String>> createDataForWindsTable() {
        List<List<String>> finalResult = new ArrayList<>();

        System.out.println("SIZE: " + finalResult.size());

        for (int i = 0; i < appSingleton.flightPlanShared.size(); i++) {
            String icao;
            String name;
            String type;

            if (appSingleton.flightPlanShared.get(i).size() > 2) {
                icao = appSingleton.flightPlanShared.get(i).get(2);
                name = appSingleton.flightPlanShared.get(i).get(1);
                type = appSingleton.flightPlanShared.get(i).get(0);
            } else {
                icao = "";
                name = "";
                type = "";
            }

            List<String> components = new ArrayList<>();

            components.add(icao);
            components.add(name);
            components.add(type);

            System.out.println("COMPONENTS: " + components);

            finalResult.add(components);
        }

        /*
         * THIS WORKS! String a1 = "LAS VEGAS/MC CARRAN "; String a2 = "KLAS";
         * String a3 = "PORTDEP";
         * 
         * List<String> a = new ArrayList<>(); a.add(a1); a.add(a2); a.add(a3);
         * 
         * String b1 = "LOS ANGELES INTL"; String b2 = "KLAX"; String b3 =
         * "PORTDEST"; List<String> b = new ArrayList<>(); b.add(b1); b.add(b2);
         * b.add(b3);
         * 
         * String c1 = "SEATTLE-TACOMA INTL"; String c2 = "KSEA"; String c3 =
         * "PORTALT"; List<String> c = new ArrayList<>(); c.add(c1); c.add(c2);
         * c.add(c3);
         * 
         * finalResult.add(a); finalResult.add(b); finalResult.add(c);
         */

        System.out.println("DATA CREATED: " + finalResult);

        return finalResult;
    }

    public Presenter getPresenter() {
        return presenter;
    }

    public void setPresenter(Presenter presenter) {
        this.presenter = presenter;
    }
}

class Presenter {
    private final View_MainFrame viewMainFrame;
    private final Model_Flightplan model;

    public Presenter(View_MainFrame viewMainFrame, Model_Flightplan model) {
        this.viewMainFrame = viewMainFrame;
        this.model = model;
    }

    public void displayTabDep() {
        CardLayout card = (CardLayout) viewMainFrame.getPanelContext().getLayout();
        card.show(viewMainFrame.getPanelContext(), "cardDep");
        viewMainFrame.addButtonsFlightplan();
        viewMainFrame.btnPnlDeparture.setEnabled(false);
    }

    public void displayTabDest() {
        CardLayout card = (CardLayout) viewMainFrame.getPanelContext().getLayout();
        card.show(viewMainFrame.getPanelContext(), "cardDest");
        viewMainFrame.addButtonsFlightplan();
        viewMainFrame.btnPnlDestination.setEnabled(false);
    }

    public void displayTabAlt() {
        CardLayout card = (CardLayout) viewMainFrame.getPanelContext().getLayout();
        card.show(viewMainFrame.getPanelContext(), "cardAlt");
        viewMainFrame.addButtonsFlightplan();
        viewMainFrame.btnPnlAlternate.setEnabled(false);
    }

    public void displayTabWindsAloft() {
        CardLayout card = (CardLayout) viewMainFrame.getPanelContext().getLayout();
        card.show(viewMainFrame.getPanelContext(), "cardWindsAloft");

        viewMainFrame.addButtonsFlightplan();
        viewMainFrame.btnPnlWindsAloft.setEnabled(false);

        viewMainFrame.createPanelWindsAloft();
    }

    public void addDeparture() {
        model.addDepartureAirport();
    }

    public void addDestination() {
        model.addDestinationAirport();
    }

    public void addAlternate() {
        model.addAlternateAirport();
    }
}

class Model_TableWindsAloft extends AbstractTableModel {

    String[] columnNames = { "ICAO", "Name", "Type" };

    private List<List<String>> tableData = new ArrayList<>();

    public Model_TableWindsAloft(List<List<String>> tableData) {
        this.tableData = tableData;
        System.out.println("CONSTRUCTOR? " + tableData);
    }

    @Override
    public int getRowCount() {
        System.out.println("DATA COUNT? " + tableData.size());
        return (tableData.size());
    }

    @Override
    public int getColumnCount() {
        return (columnNames.length);
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column];
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        System.out.println("WHAT IS DATA 1? " + tableData);

        List<String> data = tableData.get(rowIndex);

        System.out.println("WHAT IS DATA 2? " + data);

        if (data.size() >= 3) {
            switch (columnIndex) {
            case 0:
                return data.get(0);
            case 1:
                return data.get(1);
            case 2:
                return data.get(2);
            default:
                return null;
            }
        } else {
            return null;
        }
    }
}

class Model_Flightplan {
    AppSingleton appSingleton = AppSingleton.getInstance();
    private Presenter presenter;
    private View_MainFrame viewMainFrame;

    public Model_Flightplan(View_MainFrame viewMainFrame) {
        this.viewMainFrame = viewMainFrame;
    }

    public Presenter getPresenter() {
        return presenter;
    }

    public void setPresenter(Presenter presenter) {
        this.presenter = presenter;
    }

    public void addDepartureAirport() {
        List<String> component = new ArrayList<>();
        component.add("KLAS");
        component.add("KLAS");
        component.add("KLAS");

        appSingleton.flightPlanShared.set(0, component);
    }

    public void addDestinationAirport() {
        List<String> component = new ArrayList<>();
        component.add("KLAX");
        component.add("KLAX");
        component.add("KLAX");

        appSingleton.flightPlanShared.set((appSingleton.flightPlanShared.size() - 2), component);
    }

    public void addAlternateAirport() {
        List<String> component = new ArrayList<>();
        component.add("KSEA");
        component.add("KSEA");
        component.add("KSEA");

        appSingleton.flightPlanShared.set((appSingleton.flightPlanShared.size() - 1), component);
    }
}

class AppSingleton {
    private static AppSingleton instance = null;

    public List<List<String>> flightPlanShared = new ArrayList<List<String>>() {
        {
            add(Arrays.asList(""));
            add(Arrays.asList(""));
            add(Arrays.asList(""));
        }
    };

    private AppSingleton() {

    }

    public static AppSingleton getInstance() {
        if (instance == null) {
            instance = new AppSingleton();
        }
        return instance;
    }
}

关于Java 抽象表模型 : getValueAt does not use updated data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44606292/

相关文章:

java - JAVA翻译程序

java - 如何构建表单

java - 使用 AbstractTableModel 从 JTable 中删除或添加行

Java AbstractTableModel repaint();

java - 使用带有 hibernate 的 AbstractTableModel 将 Row 插入 jtable

java - 是否可以仅打印数组中的值? ( java )

java - 如何将随机数添加到 java(blackjack) 的总数中?

java - 为什么 java 程序在终止时关闭而不是 web 浏览器

java - 当我滚动放置的图像时,自行创建的图形消失

java - 如何使用计时器中 SpinnerDateModel 的更改值来执行任务?