Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何根据用户类型调整JTable行的高度?_Java_Swing_Resize_Jtable_Tablecelleditor - Fatal编程技术网

Java 如何根据用户类型调整JTable行的高度?

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

我有一个可编辑的JTable。当用户输入时,如果文本长度超过宽度,我需要增加高度。我已将换行设置为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) );
        }

    }



}
公共类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);
}

}