简体   繁体   中英

How to control height of ComboBox Editor within a JTable with large row height?

I have a JTable in which I want ComboBox editor in one column and a TextArea in another column.

When the entered TextArea includes multiple text lines I'm resizing the row height successfully, however when selecting the cell with the ComboBox Editor (in the same row) the ComboBox drop down looks a little "vertically stretched" ie it fills the whole row height.

在此处输入图片说明

Is this just how it is, or is there some way of setting the maximum or preferred height of the drop down marker of the ComboBox, so this is the same in all rows regardless of row height?

This is demonstrated in the following (with thanks to Dr Heinz at JavaSpecialists )

import java.awt.Dimension;
import java.util.Vector;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumnModel;

public class ComboAndTextAreaTest extends JFrame {
    private final JTable table = new JTable(10, 2);

    public ComboAndTextAreaTest() {
        super(System.getProperty("java.vm.version"));

        Vector boxVals = new Vector();
        boxVals.add("First");
        boxVals.add("Second");
        boxVals.add("Third");
        final JComboBox box = new JComboBox(boxVals);

        box.setSelectedIndex(0);

        final TableCellEditor boxEditor = new DefaultCellEditor(box);          

        box.setPreferredSize(new Dimension());
        TableColumnModel cmodel = table.getColumnModel();
        // First column is ComboBox based
        cmodel.getColumn(0).setCellRenderer(new DefaultTableCellRenderer());
        cmodel.getColumn(0).setCellEditor(boxEditor);
        // Second column is Text Area
        cmodel.getColumn(1).setCellRenderer(new TextAreaRenderer());
        cmodel.getColumn(1).setCellEditor(new TextAreaEditor());

        // The following doesn't appear to have any effect
        int cw = cmodel.getColumn(0).getPreferredWidth();
        Dimension pd = new Dimension(cw, 18);
        box.setMaximumSize(pd);

        String test = "The quick brown fox jumps over the lazy dog.";

        for (int row = 0; row < 10; row++) {
            table.setValueAt(boxVals.get(row % 3), row, 0);
            table.setValueAt(test, row, 1);
        }
        test = test + "\n" + test + test + test + "\n" + test + test;
        table.setValueAt(test, 4, 1);

        getContentPane().add(new JScrollPane(table));
        setSize(600, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] args) {
        new ComboAndTextAreaTest();
    }
}

EDIT: For clarity (following comments about Renderers) the following is slightly amended example removing bespoke TextArea handling. The question applies in this case as well.

JTable中的JComboBox编辑器

And the following code:

import java.util.Vector;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumnModel;

public class ComboAndTextAreaTest extends JFrame {
    private final JTable table = new JTable(10, 2);

    public ComboAndTextAreaTest() {
        super(System.getProperty("java.vm.version"));

        Vector boxVals = new Vector();
        boxVals.add("First");
        boxVals.add("Second");
        boxVals.add("Third");
        final JComboBox box = new JComboBox(boxVals);

        box.setSelectedIndex(0);

        final TableCellEditor boxEditor = new DefaultCellEditor(box);          

        TableColumnModel cmodel = table.getColumnModel();
        // First column is ComboBox based
        cmodel.getColumn(0).setCellRenderer(new DefaultTableCellRenderer());
        cmodel.getColumn(0).setCellEditor(boxEditor);
        cmodel.getColumn(0).setMaxWidth(100);
        // Second column is just text field
        cmodel.getColumn(1).setCellRenderer(new DefaultTableCellRenderer());
        cmodel.getColumn(1).setCellEditor(new DefaultCellEditor(new JTextField()));
        cmodel.getColumn(1).setPreferredWidth(200);

        String test = "The quick brown fox jumps over the lazy dog.";

        for (int row = 0; row < 10; row++) {
            table.setValueAt(boxVals.get(row % boxVals.size()), row, 0);
            table.setValueAt(test, row, 1);
        }

        // special processing on row 4 to show row height and affect on combobox
        String test2 = "This row set with greater height - combo drop down in prev cell affected during edit";

        table.setValueAt(test2, 4, 1);
        table.setRowHeight(4, 50);
        getContentPane().add(new JScrollPane(table));
        setSize(600, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] args) {
        new ComboAndTextAreaTest();
    }
}

@kleopatra (in comments on question) in response to question "Is this just how it is?" has basically answered this as "...[yes] an editor is always sized to the size of the cell, (nearly, except extremely dirty tricks :-) nothing you can do about that. A workaround might be a custom editor, fi a panel containing the combo. A bit of work involved, though".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM