【问题标题】:How do I change between two JTables?如何在两个 JTable 之间切换?
【发布时间】:2012-05-03 12:48:42
【问题描述】:

所以我在一个有效的框架内的 JScrollPane 中有一个 JTable。我想要做的是将正在显示的表更改为另一个表,该表显示一些其他信息并具有更多/更少的列/行。我该怎么做?

我已经尝试过将另一个表格放入 ScrollPane 之类的方法,但这不起作用,如果我将 ScrollPane 重新放入框架中,它就会消失。

编辑:

我认为这就是与这个问题有关的所有代码。我只是调用函数来改变视图。

    Object[][] userData = new Object[50][6];
    userTable = new JTable(userData, new String[] { "Namn", "Adress", 
            "Telefon", "Personnummer", "PIN", "Antal cyklar" }) {
        public boolean isCellEditable(int rowIndex, int colIndex) {
            return false;
        }
    };
    userTable.setSelectionMode(0);
    userTable.getTableHeader().setReorderingAllowed(false);
    Object[][] bikeData = new Object[50][7];
    bikeTable = new JTable(bikeData, new String[] { "Ägare", "Streckkod", 
            "Färg", "Märke", "Ram-nummer", "Senast hämtad", "Senast lämnad" }) {
        public boolean isCellEditable(int rowIndex, int colIndex) {
            return false;
        }
    };
    bikeTable.setSelectionMode(0);
    bikeTable.getTableHeader().setReorderingAllowed(false);
    JScrollPane tablePane = new JScrollPane(bikeTable);
    frame.add(tablePane);

    frame.setVisible(true);
}

public void displayUsers(){
    tablePane.setViewportView(userTable);
}

public void displayBikes(){
    tablePane.setViewportView(bikeTable);
}

【问题讨论】:

  • 我从不填写它们,因为提供内容的部分尚未完成。这是必须解决的问题吗?
  • 问题是你在你的方法中初始化了一个局部变量tablePane而不是类成员。在你的方法中删除tablePane 前面的JscrollPane(当然也要把它放在你的班级成员面前)
  • 如果您没有正确填写数据的所有行/列,您确实会遇到很多问题。尝试将它们全部初始化为虚拟数据。
  • 我猜当你复制粘贴太多时会发生这种情况:) 是的,如果事情变得非常糟糕,我会填满它们。
  • 现在像魅力一样工作,谢谢!

标签: java swing jtable jscrollpane


【解决方案1】:

你试过了吗:

scrollPane.setViewportView(yourNewTable);

这应该替换滚动窗格中显示的组件。当然,您可以随时更改 JTable 的模型及其列,但这不是我的偏好。

编辑:这是一个 sn-p 演示:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class Test {

    public static void main(String... args) {
        JFrame frame = new JFrame();
        final Vector<String> string = new Vector<String>();
        final JTable table = new JTable(getTableModel("First", 1));
        final JTable table2 = new JTable(getTableModel("Second", 3));
        final JButton click = new JButton("Click me");
        final JScrollPane scrollPane = new JScrollPane(table);
        click.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (table2.getParent() == null) {
                    scrollPane.setViewportView(table2);
                } else {
                    scrollPane.setViewportView(table);
                }
            }
        });
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(click, BorderLayout.EAST);
        panel.add(scrollPane);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
    }

    private static TableModel getTableModel(final String prefix, final int colCount) {
        return new TableModel() {

            @Override
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
                // TODO Auto-generated method stub

            }

            @Override
            public void removeTableModelListener(TableModelListener l) {
                // TODO Auto-generated method stub

            }

            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex) {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                return prefix + "Hello cell (" + rowIndex + "," + columnIndex + ")";
            }

            @Override
            public int getRowCount() {
                return 30;
            }

            @Override
            public String getColumnName(int columnIndex) {
                return "Column " + columnIndex;
            }

            @Override
            public int getColumnCount() {
                return colCount;
            }

            @Override
            public Class<?> getColumnClass(int columnIndex) {
                return String.class;
            }

            @Override
            public void addTableModelListener(TableModelListener l) {
                // TODO Auto-generated method stub

            }
        };
    }

}

【讨论】:

  • 我得到了 NullPointerException。如果我使用 scrollPane = new JScrollPane(otherTable) 而不是 scrollPane = new JScrollPane(currentTable),它会显示另一个表。在它们之间切换不起作用。
  • @Alex 你需要向我们展示更多代码。我只能告诉你,这是要走的路。如果需要,我将提供一个示例。
  • 我看不到维护 2 个单独的表的价值,因此您可以在它们之间切换,而在任何给定时间只会显示一个。违背了 MVC 模式的目的。
  • @Nasir 它不会破坏 MVC 模式。目的主要是性能。切换模型时,您会重新创建整个表、行、列等……这只是一个切换。您还可以维护列大小、顺序、排序等...保留它的理由有很多
  • 感谢您的示例!今晚我会更详细地检查这个:)
【解决方案2】:

如果您更改底层模型,它应该可以工作。

table.setModel(newModel)

如果您对某些单元格/列执行特殊操作,您可能还需要更新渲染器。

【讨论】:

    【解决方案3】:

    如果您要维护两个 jTable(带有两个模型),那么也许最简单的方法是简单地设置滚动窗格的视口:

    jscrollpane.setViewportView(mySecondJTable);
    

    然后切换回来:

    jscrollpane.setViewportView(myFirstJTable);
    

    【讨论】:

    • 啊,看来纪尧姆用同样的答案打败了我!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多