未在包含 JTable 的 JScrollPane 中调用 TableModel

TableModel not called in a JScrollPane containing a JTable

我在使用 Java GUI 时出现意外行为。我想创建一个包含 JTableJScrollPane,然后将此 JScrollPane 添加到 Frame

这是代码:

public class UrlsScrollPanel extends JScrollPane {
private static final long serialVersionUID = 1L;

public UrlsScrollPanel() {

    //setup urls and collections
    ArrayList<URL> urls = URL.getAll();
    ArrayList<Collection> collections = new ArrayList<>();
    for(URL url : urls) collections.add(new Collection(url));

    //table
    String[] columns = {            
        "database",
        "status",
        "consumption",
        "last snapshot date",
        "last message",
        "details",
        "stop collect"
    };  

    AbstractTableModel dataModel = new AbstractTableModel() {
        private static final long serialVersionUID = 1L;

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            System.out.printf("row: %d, column: %d \n", rowIndex, columnIndex); //is never called.
            URL url = urls.get(rowIndex);
            Collection collection = collections.get(rowIndex); 
            ArrayList<Message> lastMessages = collection.getLastSnapshot().getMessages();
            Message lastMessage = lastMessages.get(lastMessages.size() - 1);

            if(columnIndex == 0) return url.toString();
            if(columnIndex == 1) return collection.getStatus(); 
            if(columnIndex == 2) return ConsumptionChart.getChartPanel(collection);
            if(columnIndex == 3) return collection.getLastSnapshot().getDate();
            if(columnIndex == 4) return String.format("[ %s ] %s", lastMessage.getDate(), lastMessage.getBody()); 
            return "Comming soon.";
        }

        @Override
        public int getRowCount() {
            return urls.size();
        }

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

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    };
    JTable table = new JTable(dataModel);
    add(table);
    setBackground(Color.red);
    setSize(500, 500);
}
}

我是这样称呼它的:

public static void main(String[] args) {        
    JFrame frame = new JFrame();
    frame.setVisible(true);
    frame.setResizable(true);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH );
    frame.setLocationRelativeTo(null);
    UrlsScrollPanel panel = new UrlsScrollPanel();
    frame.add(panel, BorderLayout.CENTER);
    SwingUtilities.updateComponentTreeUI(frame);
}

结果是一个红色方块在框架的左上角闪烁,然后立即消失。另外 dataModel 似乎从未被调用过。

非常感谢对我做错的任何帮助,感谢您的宝贵时间!

不要延长 JScrollPane。相反,使用你的table构造一个JScrollPane:

frame.add(new JScrollPane(table), BorderLayout.CENTER);

描述了方法 here; a complete example is shown here; an alternative approach using setViewportView() is examined

Are these two not similar?

JScrollPane panel = new JScrollPane(); panel.add(table);
…
JScrollPane panel = new JScrollPane(table);

没有。如How a Scroll Pane Works, the first formulation adds the table directly to the JScrollPane, replacing the JViewport component that occupies the central position in the ScrollPaneLayout所示,那将被用来显示table。第二个公式在内部调用 setViewportView(table),它告诉滚动窗格的 JViewport 要显示的组件。