Java 如何根据用户类型调整JTable行的高度?
我有一个可编辑的JTable。当用户输入时,如果文本长度超过宽度,我需要增加高度。我已将换行设置为true,但它仅在用户按enter键后更改高度。我错过了什么?我已经看到了解决大小调整问题的答案(例如在cellRenderer中),但我需要在用户键入时调整高度,而不是在用户完成键入后Java 如何根据用户类型调整JTable行的高度?,java,swing,resize,jtable,tablecelleditor,Java,Swing,Resize,Jtable,Tablecelleditor,我有一个可编辑的JTable。当用户输入时,如果文本长度超过宽度,我需要增加高度。我已将换行设置为true,但它仅在用户按enter键后更改高度。我错过了什么?我已经看到了解决大小调整问题的答案(例如在cellRenderer中),但我需要在用户键入时调整高度,而不是在用户完成键入后 public class EndCycleCellEditor extends AbstractCellEditor implements TableCellEditor, KeyListener { J
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) );
}
}
}
公共类EndCycleCellEditor扩展AbstractCellEditor实现TableCellEditor、KeyListener{
jc组件;
private ArrayList rowColHeight=new ArrayList();
公共endCycleCeleditor(){
组件=新的JTextArea();
((JTextArea)组件)setWrapStyleWord(true);
((JTextArea)组件)。setLineWrap(true);
addKeyListener(这个);
}
@凌驾
公共对象getCellEditorValue(){
return((JTextArea)组件).getText();
}
@凌驾
公共组件getTableCellEditorComponent(JTable表、对象值、,
布尔值(选定,int行,int列){
((JTextArea)组件).setText(value.toString());
返回组件;
}
@凌驾
public void keyTyped(KeyEvent e){
//TODO自动生成的方法存根
}
@凌驾
按下公共无效键(按键事件e){
//TODO自动生成的方法存根
}
@凌驾
公共无效密钥已释放(密钥事件e){
if(((JTextArea)组件).getText().length()>=200){
getDefaultToolkit().beep();
((JTextArea)component.setText((JTextArea)component.getText().substring(0200));
}
}
}
1)这种调整大小的方法是可行的,但不美观且不便于用户使用
2) 不要使用非标准hack作为JTable中的多行跨度
3) 设置为,但是您必须在另一个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;
}
}
1) 这种方式可以调整大小,但不美观且不便于用户使用
2) 不要使用非标准hack作为JTable中的多行跨度
3) 设置为,但是您必须在另一个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;
}
}
[编辑:我最初的回答有一些错误和暗示。同时,我根据各种例子找到了一个更优雅的解决方案。] 这个解决方案基于-我做了一些错误修复(主要是:从编辑器中删除了行高计算,在渲染器中添加了行高计算) 上的建议非常有助于使其更加美观(例如,为表格添加颜色和字体) 总之,该解决方案使用多行渲染JTable单元格。当输入或删除文本时,编辑器会自动更新行高。行高的计算留待TextArea的首选大小 第一步:细胞渲染器
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);
}
}
}
public类multilecellrenderer扩展JTextArea实现
TableCell渲染器{
公共多容器渲染器(){
可编辑设置(假);
setLineWrap(真);
setWrapStyleWord(true);
}
公共组件GetTableCellRenderComponent(JTable表、对象值、,
布尔值(已选择,布尔值为焦点,整数行,整数列){
if(字符串的值实例){
setText((字符串)值);
//我们设置宽度和强制textarea以重新计算首选高度
设置大小(table.getColumnModel().getColumn(column).getWidth(),1000);
//在这种方法中,我们不应执行以下操作。
//它似乎创造了一个无止境的循环
//int rowHeight=table.getRowHeight(行);
//int cellHeight=getPreferredSize().height;
//如果(单元高度>行高度)
//表.设置行高(行、单元高);
}否则
setText(“”);
归还这个;
}
/*
*确保在表更改时调用此方法。
*从相应的TableCellRenderer、TableModelListener调用它,
*ComponentListener,TableColumnModelListener。
*/
public void updateRowHeights(){
对于(int row=0;row行高度)
行高=单元高度;
}
表.设置行高(行,行高);
}
}
}
步骤2:CellEditor(我假设有一个可能的更短的解决方案,而不覆盖JTextArea)
公共类multilecelleditor扩展AbstractCellEditor实现
TableCellEditor{
MyTextArea textArea;
JTable表;
公共多接收器编辑器(JTable ta){
超级();
表=ta;
//此组件依赖于为字符串提供此渲染器
//阶级
MultilecellRenderer=新的MultilecellRenderer();
table.setDefaultRenderer(String.class,renderer);
textArea=新的MyTextArea();
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
}
公共对象getCellEditorValue(){
返回textArea.getText();
}
公共组件getTableCellEditorComponent(JTable表、对象值、,
布尔值(选定,int行,int列){
textArea.setText(table.getValueAt(行、列).toString());
textArea.rowEditing=行;
textArea.columnEditing=列;
textArea.lastPreferredHeight=textArea.getPreferredSize().height;
返回文本区;
}
/**
*此方法确定给定文本的单元格的高度(以像素为单位)
*包含
*/
专用内部单元高度(内部行、内部列){
if(row==table.getEditingRow()&&col==table.getEditingColumn())
返回textArea.getPreferredS
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);
}
}