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。
对于作业,我们必须将 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。