JScrollpane中的JTable调整显示组件的高度

发布于 2024-12-11 16:10:10 字数 4854 浏览 0 评论 0原文

我在 jscrollpane 中有一个 jtable。我使用 jgoodies 表单布局并将滚动窗格放在设置为“pref”的行中。这是表格现在的样子:

在此处输入图像描述

我顺便使用 swingx JXTable 并设置了visibleRowCount为2。但只显示半行。

在制作 SSCCE 时,我意识到它无法正常工作,因为我有一个自定义的 TextAreaRenderer。我认为由于这个渲染器,行高没有被正确计算。我试图找出原因,同时如果你们能发现它那就太好了......

public static void main(String[] args) {
    JFrame frame=new JFrame();
    JPanel panel=new FormDebugPanel();
    frame.setContentPane(panel);
    FormLayout layout=new FormLayout("1dlu:grow,200dlu:grow,1dlu:grow",
            "10dlu,pref,5dlu,pref,10dlu");
    panel.setLayout(layout);
    String[] columns= {"1st Column","2nd Column","3rd Column"};
    String[][] data= {
            {"Sethu","Data","Something\nis\nhere"},
            {"Sethu","Data","Something\nis\nhere"},

    };
    JXTable table=new JXTable(data,columns);
    table.setVisibleRowCount(2);

    TableColumnModel columnModel=table.getColumnModel();
    columnModel.getColumn(2).setCellRenderer(new TextAreaRenderer());

    JScrollPane scrlPan=new JScrollPane(table);
    CellConstraints cc=new CellConstraints();
    panel.add(scrlPan, cc.xy(2, 2));
    panel.add(new JLabel("Label After Table"),cc.xy(2,4));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
}

这是渲染器:

class TextAreaRenderer extends JTextArea implements TableCellRenderer {

private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();

/** map from table to map of rows to map of column heights */
private final Map<JTable,Map<Integer,Map<Integer,Integer>>> cellSizes = new HashMap<JTable,Map<Integer,Map<Integer,Integer>>>();

public TextAreaRenderer() {
    setLineWrap(true);
    setWrapStyleWord(true);
}

public Component getTableCellRendererComponent(//
        JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
    // set the colours, etc. using the standard for that platform
    adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
    setForeground(adaptee.getForeground());
    setBackground(adaptee.getBackground());
    setBorder(adaptee.getBorder());
    setFont(adaptee.getFont());
    setText(adaptee.getText());

    // This line was very important to get it working with JDK1.4
    TableColumnModel columnModel = table.getColumnModel();
    setSize(columnModel.getColumn(column).getWidth(), 100000);
    int height_wanted = (int) getPreferredSize().getHeight();
    addSize(table, row, column, height_wanted);
    height_wanted = findTotalMaximumRowSize(table, row);
    if (height_wanted != table.getRowHeight(row)) {
        table.setRowHeight(row, height_wanted);
    }
    return this;
}

private void addSize(JTable table, int row, int column, int height) {
    Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table);
    if (rows == null) {
        cellSizes.put(table, rows = new HashMap<Integer,Map<Integer,Integer>>());
    }
    Map<Integer,Integer> rowheights =  rows.get(new Integer(row));
    if (rowheights == null) {
        rows.put(new Integer(row), rowheights = new HashMap<Integer,Integer>());
    }
    rowheights.put(new Integer(column), new Integer(height));
}

/**
 * Look through all columns and get the renderer. If it is also a
 * TextAreaRenderer, we look at the maximum height in its hash table for
 * this row.
 */
private int findTotalMaximumRowSize(JTable table, int row) {
    int maximum_height = 0;
    Enumeration<TableColumn> columns = table.getColumnModel().getColumns();
    while (columns.hasMoreElements()) {
        TableColumn tc = (TableColumn) columns.nextElement();
        TableCellRenderer cellRenderer = tc.getCellRenderer();
        if (cellRenderer instanceof TextAreaRenderer) {
            TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
            maximum_height = Math.max(maximum_height, tar.findMaximumRowSize(table, row));
        }
    }
    return maximum_height;
}

private int findMaximumRowSize(JTable table, int row) {
    Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table);
    if (rows == null)
        return 0;
    Map<Integer,Integer> rowheights = rows.get(new Integer(row));
    if (rowheights == null)
        return 0;
    int maximum_height = 0;
    for (Iterator<Map.Entry<Integer, Integer>> it = rowheights.entrySet().iterator(); it.hasNext();) {
        Map.Entry<Integer,Integer> entry = it.next();
        int cellHeight = ((Integer) entry.getValue()).intValue();
        maximum_height = Math.max(maximum_height, cellHeight);
    }
    return maximum_height;
}
}

当我使用 TextAreaRenderer 时,setVisibleRowHeight() 没有正确执行。我认为这与没有在渲染器中正确设置行高有关。

I have a jtable within a jscrollpane. I use the jgoodies Form Layout and have put the scrollpane in a row that is set to "pref". This is how the table looks like right now:

enter image description here

I am using swingx JXTable by the way and have set the visibleRowCount to 2. But only half a row is displayed.

While making the SSCCE I realised that its not working properly because I have a custom TextAreaRenderer. I think because of this renderer, the row height is not being calculated properly. I am trying to figure out why, in the meantime if you guys can spot it that would be great...

public static void main(String[] args) {
    JFrame frame=new JFrame();
    JPanel panel=new FormDebugPanel();
    frame.setContentPane(panel);
    FormLayout layout=new FormLayout("1dlu:grow,200dlu:grow,1dlu:grow",
            "10dlu,pref,5dlu,pref,10dlu");
    panel.setLayout(layout);
    String[] columns= {"1st Column","2nd Column","3rd Column"};
    String[][] data= {
            {"Sethu","Data","Something\nis\nhere"},
            {"Sethu","Data","Something\nis\nhere"},

    };
    JXTable table=new JXTable(data,columns);
    table.setVisibleRowCount(2);

    TableColumnModel columnModel=table.getColumnModel();
    columnModel.getColumn(2).setCellRenderer(new TextAreaRenderer());

    JScrollPane scrlPan=new JScrollPane(table);
    CellConstraints cc=new CellConstraints();
    panel.add(scrlPan, cc.xy(2, 2));
    panel.add(new JLabel("Label After Table"),cc.xy(2,4));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
}

And here's the renderer:

class TextAreaRenderer extends JTextArea implements TableCellRenderer {

private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();

/** map from table to map of rows to map of column heights */
private final Map<JTable,Map<Integer,Map<Integer,Integer>>> cellSizes = new HashMap<JTable,Map<Integer,Map<Integer,Integer>>>();

public TextAreaRenderer() {
    setLineWrap(true);
    setWrapStyleWord(true);
}

public Component getTableCellRendererComponent(//
        JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
    // set the colours, etc. using the standard for that platform
    adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
    setForeground(adaptee.getForeground());
    setBackground(adaptee.getBackground());
    setBorder(adaptee.getBorder());
    setFont(adaptee.getFont());
    setText(adaptee.getText());

    // This line was very important to get it working with JDK1.4
    TableColumnModel columnModel = table.getColumnModel();
    setSize(columnModel.getColumn(column).getWidth(), 100000);
    int height_wanted = (int) getPreferredSize().getHeight();
    addSize(table, row, column, height_wanted);
    height_wanted = findTotalMaximumRowSize(table, row);
    if (height_wanted != table.getRowHeight(row)) {
        table.setRowHeight(row, height_wanted);
    }
    return this;
}

private void addSize(JTable table, int row, int column, int height) {
    Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table);
    if (rows == null) {
        cellSizes.put(table, rows = new HashMap<Integer,Map<Integer,Integer>>());
    }
    Map<Integer,Integer> rowheights =  rows.get(new Integer(row));
    if (rowheights == null) {
        rows.put(new Integer(row), rowheights = new HashMap<Integer,Integer>());
    }
    rowheights.put(new Integer(column), new Integer(height));
}

/**
 * Look through all columns and get the renderer. If it is also a
 * TextAreaRenderer, we look at the maximum height in its hash table for
 * this row.
 */
private int findTotalMaximumRowSize(JTable table, int row) {
    int maximum_height = 0;
    Enumeration<TableColumn> columns = table.getColumnModel().getColumns();
    while (columns.hasMoreElements()) {
        TableColumn tc = (TableColumn) columns.nextElement();
        TableCellRenderer cellRenderer = tc.getCellRenderer();
        if (cellRenderer instanceof TextAreaRenderer) {
            TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
            maximum_height = Math.max(maximum_height, tar.findMaximumRowSize(table, row));
        }
    }
    return maximum_height;
}

private int findMaximumRowSize(JTable table, int row) {
    Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table);
    if (rows == null)
        return 0;
    Map<Integer,Integer> rowheights = rows.get(new Integer(row));
    if (rowheights == null)
        return 0;
    int maximum_height = 0;
    for (Iterator<Map.Entry<Integer, Integer>> it = rowheights.entrySet().iterator(); it.hasNext();) {
        Map.Entry<Integer,Integer> entry = it.next();
        int cellHeight = ((Integer) entry.getValue()).intValue();
        maximum_height = Math.max(maximum_height, cellHeight);
    }
    return maximum_height;
}
}

When I use the TextAreaRenderer, then the setVisibleRowHeight() is not honoured correctly. I think it has something to do with not setting the row height properly in the renderer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

失而复得 2024-12-18 16:10:10

使用 JXTable,您可以配置最初显示的行数(或列数):

    table.setVisibleRowCount(2)

这是一个快速片段,显示如何设置行数的初始大小并动态更新 TableModelListener 中的首选项高度

    final JXTable table = new JXTable(3, 5);
    table.setVisibleRowCount(table.getRowCount());
    TableModelListener l = new TableModelListener() {

        @Override
        public void tableChanged(TableModelEvent e) {
            if (!(e.getType() == TableModelEvent.INSERT)) return;
            table.setVisibleRowCount(((TableModel) e.getSource()).getRowCount());
            RootPaneContainer frame = (RootPaneContainer) SwingUtilities.windowForComponent(table);
            ((JComponent) frame.getContentPane()).revalidate();
        }
    };
    table.getModel().addTableModelListener(l);
    Action insert = new AbstractAction("add row") {

        @Override
        public void actionPerformed(ActionEvent e) {
            ((DefaultTableModel) table.getModel()).addRow(new Object[] {});
        }
    };
    new Timer(500, insert).start();
    JComponent comp = new JPanel(new MigLayout());
    comp.add(new JScrollPane(table));
    JXFrame frame = wrapInFrame(comp, "visibleRowCount");
    show(frame, frame.getPreferredSize().width, frame.getPreferredSize().height * 4);

With JXTable, you can configure how many rows (or columns) to show initially:

    table.setVisibleRowCount(2)

Here's a quick snippet showing how-to set the initial size in terms of rows and dynamically update the pref height in a TableModelListener

    final JXTable table = new JXTable(3, 5);
    table.setVisibleRowCount(table.getRowCount());
    TableModelListener l = new TableModelListener() {

        @Override
        public void tableChanged(TableModelEvent e) {
            if (!(e.getType() == TableModelEvent.INSERT)) return;
            table.setVisibleRowCount(((TableModel) e.getSource()).getRowCount());
            RootPaneContainer frame = (RootPaneContainer) SwingUtilities.windowForComponent(table);
            ((JComponent) frame.getContentPane()).revalidate();
        }
    };
    table.getModel().addTableModelListener(l);
    Action insert = new AbstractAction("add row") {

        @Override
        public void actionPerformed(ActionEvent e) {
            ((DefaultTableModel) table.getModel()).addRow(new Object[] {});
        }
    };
    new Timer(500, insert).start();
    JComponent comp = new JPanel(new MigLayout());
    comp.add(new JScrollPane(table));
    JXFrame frame = wrapInFrame(comp, "visibleRowCount");
    show(frame, frame.getPreferredSize().width, frame.getPreferredSize().height * 4);
悸初 2024-12-18 16:10:10
setPreferredScrollableViewportSize(Dimension)

是你应该研究的事情。这是一个很好的教程:如何使用滚动窗格

setPreferredScrollableViewportSize(Dimension)

is something you should look into. and here is a good tutorial : How to Use Scroll Panes

公布 2024-12-18 16:10:10

我相信您可以使用 JSCrollPane 的 PreferredSize、minSize 和 maxSize 属性来实现此目的。如果您将preferredSize 设置为您想要的最小尺寸,并将maxsize 设置为您想要的最大尺寸,那么它应该可以工作。

I believe you can use preferredSize, minSize and maxSize properties of the JSCrollPane to achieve this. If you set preferredSize to the minimum size you want and the maxsize to the maximum size you want, it should work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文