[英]How do I resize the height of a JTable row as the user types?
我有一個可編輯的JTable。 當用戶鍵入內容時,如果文本長於寬度,則需要增加高度。 我已經將linewrap設置為true,但是它僅在用戶按下Enter鍵之后才更改高度。 我想念什么? 我已經看過該解決的問題調整大小(如回答這個在cellRenderer的,但我需要調整高度的用戶類型,他們完成打字而不是之后。
public class EndCycleCellEditor extends AbstractCellEditor implements TableCellEditor, KeyListener {
JComponent component;
private ArrayList<ArrayList<Integer>> rowColHeight = new ArrayList<ArrayList<Integer>>();
public EndCycleCellEditor(){
component = new JTextArea();
((JTextArea) component).setWrapStyleWord(true);
((JTextArea) component).setLineWrap(true);
component.addKeyListener(this);
}
@Override
public Object getCellEditorValue() {
return ((JTextArea) component).getText();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
((JTextArea)component).setText(value.toString());
return component;
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
if(((JTextArea) component).getText().length() >= 200){
Toolkit.getDefaultToolkit().beep();
((JTextArea)component).setText(((JTextArea)component).getText().substring(0,200) );
}
}
}
1)可以通過這種方式調整大小,但是難看並且不方便用戶使用
2)不要使用non_standard hack,因為JTable中的MultiLines跨度
3)把JTextArea中的JScrollPane的 ,但你必須要超控滾動JScrollPane
另一個內JScrollPane
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
class JTableMultiLineSupport extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private static final long serialVersionUID = 1L;
private JTextArea editor = new JTextArea(4, 10);
private JScrollPane jsp = new JScrollPane(editor);
private JTable table;
private int row;
private int col;
private JTextArea renderer = new JTextArea(4, 10);
public static void main(String[] args) {
JTable table = new JTable(new String[][]{
{"1\n2\n3\n4\n5\n6\n7", "1\n2\n3\n4\n5\n6\n7", "1\n2\n3\n4\n5\n6\n7"},
{"1\n2\n3\n4\n5\n6\n7", "1\n2\n3\n4\n5\n6\n7", "1\n2\n3\n4\n5\n6\n7"}},
new String[]{"First Column", "Second Column", "Third Column"});
JTableMultiLineSupport mls = new JTableMultiLineSupport();
table.setDefaultEditor(Object.class, mls);
table.setDefaultRenderer(Object.class, mls);
table.setRowHeight(0, 30);
table.setRowHeight(1, 70);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JFrame frame = new JFrame("Test");
frame.add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int col) {
this.table = table;
this.row = row;
this.col = col;
editor.setText(value.toString());
return jsp;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
renderer.setText(value == null ? "" : value.toString());
renderer.setEnabled(false);
return renderer;
}
@Override
public Object getCellEditorValue() {
return editor.getText();
}
@Override
public boolean stopCellEditing() {
table.getModel().setValueAt(editor.getText(), row, col);
return true;
}
}
[編輯:我最初的回答有一些錯誤和含義。 同時,基於各種示例,我找到了一個更優雅的解決方案。]
此解決方案基於http://www.coderanch.com/t/336033/GUI/java/MultiLine-JTable-盡管我做了一些錯誤修復((大多數情況:從編輯器中刪除了rowHeights的計算,將rowHeight的計算添加到了Renderer中) )。
http://blog.botunge.dk/post/2009/10/09/JTable-multiline-cell-renderer.aspx上的建議非常有用 ,可以使其更美觀(例如,為表格添加顏色和字體)。
綜上所述,此解決方案使用多行呈現JTable單元。 輸入或刪除文本時,編輯器會自動更新行高。 行高的計算留給TextArea的preferredSize。
第一步:CellRenderer
public class MultiLineCellRenderer extends JTextArea implements
TableCellRenderer {
public MultiLineCellRenderer() {
setEditable(false);
setLineWrap(true);
setWrapStyleWord(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof String) {
setText((String) value);
// We set the width and force textarea to recompute the preferred height
setSize(table.getColumnModel().getColumn(column).getWidth(), 1000);
// we should not do the following in this method.
// it seems to create an endless loop
// int rowHeight = table.getRowHeight(row);
// int cellHeight = getPreferredSize().height;
// if (cellHeight > rowHeight)
// table.setRowHeight(row, cellHeight);
} else
setText("");
return this;
}
/*
* Make sure to call this method, whenever the table changes.
* Call it from appropriate TableCellRenderer, TableModelListener,
* ComponentListener, TableColumnModelListener.
*/
public void updateRowHeights() {
for (int row = 0; row < table.getRowCount(); row++) {
int rowHeight = 0;
for (int col = 0; col < table.getColumnCount(); col++) {
Object value = table.getValueAt(row, col);
if (value != null)
setText(value.toString());
else
setText("");
setSize(table.getColumnModel().getColumn(col).getWidth(), 1000);
int cellHeight = getPreferredSize().height;
if (cellHeight > rowHeight)
rowHeight = cellHeight;
}
table.setRowHeight(row, rowHeight);
}
}
}
步驟2:CellEditor(我假設有一個更短的解決方案,而不會覆蓋JTextArea)。
public class MultiLineCellEditor extends AbstractCellEditor implements
TableCellEditor {
MyTextArea textArea;
JTable table;
public MultiLineCellEditor(JTable ta) {
super();
table = ta;
// this component relies on having this renderer for the String
// class
MultiLineCellRenderer renderer = new MultiLineCellRenderer();
table.setDefaultRenderer(String.class, renderer);
textArea = new MyTextArea();
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
}
public Object getCellEditorValue() {
return textArea.getText();
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
textArea.setText(table.getValueAt(row, column).toString());
textArea.rowEditing = row;
textArea.columnEditing = column;
textArea.lastPreferredHeight = textArea.getPreferredSize().height;
return textArea;
}
/**
* This method determines the height in pixel of a cell given the text it
* contains
*/
private int cellHeight(int row, int col) {
if (row == table.getEditingRow() && col == table.getEditingColumn())
return textArea.getPreferredSize().height;
else
return table
.getDefaultRenderer(String.class)
.getTableCellRendererComponent(table,
table.getModel().getValueAt(row, col), false,
false, row, col).getPreferredSize().height;
}
void cellGrewEvent(int row, int column) {
updateRow(row);
}
void cellShrankEvent(int row, int column) {
updateRow(row);
}
void updateRow(int row) {
int maxHeight = 0;
for (int j = 0; j < table.getColumnCount(); j++) {
int ch;
if ((ch = cellHeight(row, j)) > maxHeight) {
maxHeight = ch;
}
}
table.setRowHeight(row, maxHeight);
}
class MyTextArea extends JTextArea implements KeyListener {
private static final long serialVersionUID = 1L;
int lastPreferredHeight = 0;
int rowEditing;
int columnEditing;
MyTextArea() {
addKeyListener(this);
// This is a fix to Bug Id 4256006
addAncestorListener(new AncestorListener() {
public void ancestorAdded(AncestorEvent e) {
requestFocus();
}
public void ancestorMoved(AncestorEvent e) {
}
public void ancestorRemoved(AncestorEvent e) {
}
});
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
if (getPreferredSize().getHeight() > lastPreferredHeight) {
lastPreferredHeight = getPreferredSize().height;
cellGrewEvent(rowEditing, columnEditing);
// this will trigger the addition of extra lines upon the
// cell growing and prevent all the text being lost when
// the cell grows to the point of requiring scrollbars
table.setValueAt(getText(), rowEditing, columnEditing);
} else if (getPreferredSize().getHeight() < lastPreferredHeight) {
lastPreferredHeight = getPreferredSize().height;
cellShrankEvent(rowEditing, columnEditing);
} else if (table.getValueAt(rowEditing, columnEditing).equals(""))
table.setValueAt(getText(), rowEditing, columnEditing);
}
}
}
這里是一些測試它的代碼。
public class MultiLineCellExample extends JFrame {
private static final long serialVersionUID = 1L;
public MultiLineCellExample() {
DefaultTableModel dm = new DefaultTableModel() {
private static final long serialVersionUID = 1L;
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
};
dm.setDataVector(
new Object[][] {
{ "aa TEST TEST TEST TEST TEST TEST TEST TEST END",
"bb", "cc" }, { "A\nA", "B\nB", "C\nC" } },
new Object[] { "1", "2", "3" });
JTable table = new JTable(dm);
MultiLineCellEditor editor = new MultiLineCellEditor(table);
table.setDefaultEditor(String.class, editor);
dm.fireTableRowsInserted(0, 0);
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll);
}
public static void main(String[] args) {
MultiLineCellExample mlce = new MultiLineCellExample();
mlce.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mlce.setSize(400, 400);
mlce.pack();
mlce.setVisible(true);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.