Java JTable 未在 MacOS 上显示,但在 Windows 上显示

Java JTable not showing on MacOS but on Windows

对于作业,我们必须将 XML 文件解析为 JTable。我们创建了一个从 JFileChooser 获取目标文件的 ParserClass。在解析 XML 之后,我们的程序将所需的数据移交给我们的 JTable 的 TableModel。我们在 Eclipse 中 Windows 上测试了程序,JTable 完美地显示了我们解析的数据。

我的问题是: 当我尝试 运行 MacOS(intellij 或 Eclipse)上的代码时,JTable 没有刷新 TabelModel,所以我们的 JTable没有显示任何数据。 我们的代码尚未清理,但我想确定为什么 Windows 会刷新 TableModel 而 MacOS 不会。

GUI Class 代码:

public class GUI extends JFrame {
    
    //Attribute
    private XmlParser myParser = new XmlParser();
        
    //Main-Methode
    public static void main(String[] args)throws SAXException, IOException,
    ParserConfigurationException, TransformerException {
        
        //GUI wird erstellt
        GUI myGui = new GUI();
        myGui.setDefaultCloseOperation(EXIT_ON_CLOSE);;
        myGui.setBounds(100, 100, 606, 437);
        myGui.setTitle("TITEL");
        myGui.setVisible(true);     
    }

    //Konstruktor für die GUI
    public GUI() {
        
        JTable myTable = new JTable(new TableModel());
        myTable.setShowGrid(false);
        
        JPanel contentPane = new JPanel();
        
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        
        JMenu dateiMenu = new JMenu("Datei");
        menuBar.add(dateiMenu);
        
        JMenuItem neuMenuItem = new JMenuItem("Neu");
        dateiMenu.add(neuMenuItem);
        
        JMenuItem openMenuItem = new JMenuItem("Öffnen");
        openMenuItem.addActionListener(new ActionListener() {
            
        public void actionPerformed(ActionEvent e) {
            JFileChooser openFile = new JFileChooser();
            openFile.addChoosableFileFilter(new FileNameExtensionFilter("Images", "jpg", "png", "gif", "bmp"));
            openFile.addChoosableFileFilter(new FileNameExtensionFilter("*.xml", "xml"));
            openFile.setDialogTitle("Datei auswählen"); 
            int rueckgabeWert = openFile.showOpenDialog(null);  
            
            //Testet, ob Button gedrückt wurde und gibt den Dateinamen dann raus
            if (rueckgabeWert == JFileChooser.APPROVE_OPTION) {
                
                String newXmlFile = openFile.getSelectedFile().getName();
                System.out.println(openFile.getSelectedFile().getName());
                
                //XML wird zum parsen übergeben
                myParser.xmlToDocument(newXmlFile);
                
                //neues TableModel mit idListe für das Initialisieren des data-Arrays(Zeilen der Tabelle)
                TableModel myNewTableModel = new TableModel(myParser.idListe, myParser.mengeListe, myParser.einheitListe, myParser.kurztextListe);

                //übergibt neues TableModel an Tabelle
                myTable.setModel(myNewTableModel);



            } 
        }
        });
        dateiMenu.add(openMenuItem);
        
        JMenuItem saveMenuItem = new JMenuItem("Speichern");
        dateiMenu.add(saveMenuItem);
        
        JMenuItem quitMenuItem = new JMenuItem("Beenden");
        quitMenuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        dateiMenu.add(quitMenuItem);
        
        //ContentPane + ScrollPane werden erzeugt
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(new BorderLayout(0, 0));
        
        JScrollPane scrollPane = new JScrollPane(myTable);
        contentPane.add(scrollPane);
    }
    
    
    
    //TabelModel-Klasse
    public class TableModel extends AbstractTableModel {
        
        private String[] columnNames = {"Ordinalzahl", "Menge", "Einheit", "Kurztext"};
        private Object[][] data = {};
        
        //leerer Konstruktor
        public TableModel() {
        };
        
        //Konstruktor nach dem Parsen
        public TableModel (ArrayList<String> idListe, ArrayList<String> mengeListe, ArrayList<String> einheitListe, ArrayList<String> kurztextListe) {      
            this.data = new Object[idListe.size()][4];  
            
            for (int i = 0; i < idListe.size(); i++) {
                for (int j = 0; j < 4; j++) {
                    if (j==0) {
                        this.data [i][j] = idListe.get(i);
                    }
                    if (j==1) {
                        this.data [i][j] = mengeListe.get(i);
                    }
                    if (j==2) {
                        this.data [i][j] = einheitListe.get(i);
                    }
                    if (j==3) {
                        this.data [i][j] = kurztextListe.get(i);
                    }
                }
            }
            
        }
    
        public int getColumnCount() {
            return columnNames.length;
        }
        
        public int getRowCount(){
            return data.length;
        }
        
        public String getColumnName(int idx) {
            return columnNames[idx];
        }
        
        public Object getValueAt(int row, int col) {
            return data[row][col];
        }
        
        public void setValueAt(Object val, int row, int col) {
            data[row][col] = val;
        }
        
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }
        
        public boolean isCellEditable(int row, int col) {
            if (col<3)
                return false;
            else 
                return true;
        }
    }   
}
myGui.setVisible(true); 

应该是:

/* Prompt the JRE to layout the components & size the GUI 
just large enough to display those components. */
myGui.pack();
myGui.setVisible(true); 

删除:

myGui.setBounds(100, 100, 606, 437); 

这个尺寸只是一个猜测。 GUI 的正确大小是通过根据组件的首选大小布置组件,然后调用 pack() 来提供的。另见 this answer to Best practice for setting JFrame locations