JTable в JScrollpane настроить высоту отображаемого компонента - PullRequest
4 голосов
/ 24 октября 2011

У меня есть jtable внутри jscrollpane.Я использую jgoodies Form Layout и поместил полосу прокрутки в строку, которая установлена ​​на «pref».Вот как выглядит таблица прямо сейчас:

enter image description here

Кстати, я использую 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 () не соблюдается правильно.Я думаю, что это связано с неправильной установкой высоты строки в рендере.

Ответы [ 3 ]

4 голосов
/ 24 октября 2011

С помощью 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);
2 голосов
/ 24 октября 2011
setPreferredScrollableViewportSize(Dimension)

это то, что вы должны посмотреть.и вот хороший урок: Как использовать панели прокрутки

1 голос
/ 24 октября 2011

Я полагаю, что для достижения этой цели вы можете использовать свойства предпочитаемого размера, минимального размера и максимального размера панели управления.Если вы установили предпочитаемый размер как минимальный, а максимальный размер - по желанию, он должен работать.

...