JTextAreasを含むようにJTable列を作成する方法を教えてください。ユーザーが大量のテキストを入力するとセルの高さが増加し、複数の行が表示されます(セルが展開され、その結果、行も展開されます)
質問する
2118 次
2 に答える
4
JTextArea に基づいて、独自のセル レンダラーとエディターを作成する必要があります。
public class Start
{
public static class JTextPaneCellEditor extends AbstractCellEditor implements TableCellEditor, KeyListener
{
private JViewport viewport;
private JTable table;
private int row;
private JTextPane pane;
public JTextPaneCellEditor(){
viewport = new JViewport();
pane = new JTextPane();
viewport.add(pane);
pane.addKeyListener(this);
}
@Override public Object getCellEditorValue(){
return pane.getText();
}
@Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column){
this.table = table;
this.row = row;
pane.setText(value.toString());
int newHeight = (int)pane.getPreferredSize().getHeight();
if(table.getRowHeight(row) < newHeight){
table.setRowHeight(row, newHeight);
}
return pane;
}
@Override public boolean isCellEditable(EventObject e){
if (e instanceof MouseEvent) {
return ((MouseEvent)e).getClickCount() >= 2;
}
return true;
}
@Override public void keyTyped(KeyEvent e){
table.setRowHeight(row, (int)pane.getPreferredSize().getHeight());
}
@Override public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_ENTER){
stopCellEditing();
}
}
@Override public void keyReleased(KeyEvent e){
}
}
private static class JTextPaneCellRenderer extends JViewport implements TableCellRenderer
{
JTextPane pane;
JTextPaneCellRenderer(){
pane = new JTextPane();
add(pane);
}
@Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
pane.setText(value.toString());
table.setRowHeight(row, (int)pane.getPreferredSize().getHeight());
return this;
}
}
public static void main(String[] args){
JTable table = new JTable(new String[][]{{"String String String String StringString String String String StringString String String String StringString String String String StringString String String String String"}, {"String 2"}}, new String[]{"Column"});
table.setDefaultRenderer(Object.class, new JTextPaneCellRenderer());
table.setDefaultEditor(Object.class, new JTextPaneCellEditor());
JFrame test = new JFrame();
test.add(new JScrollPane(table));
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setSize(300, 300);
test.setLocationRelativeTo(null);
test.setVisible(true);
}
}
編集: より良いサイズ設定のためにビューポートを追加します。ただし、最初の編集では行はまだ展開されていません。誰にもアイデアはありますか?
EDIT2:コメントに同意します。あなたが望むことは可能ですが、テストされていないハックなカスタム実装が必要です. このような JTable ソーサリーを除外するようにレイアウトを再設計した方がよいでしょう。
于 2012-04-24T21:48:11.817 に答える
2
@ヤクブ・ザヴェルカ
この回答は後で削除します
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
public class AutoWrapTest {
public JComponent makeUI() {
String[] columnNames = {"TextAreaCellRenderer"};
Object[][] data = {
{"123456789012345678901234567890"},
{"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddx"},
{"----------------------------------------------0"},
{">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>|"},};
TableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
JTable table = new JTable(model) {
private static final long serialVersionUID = 1L;
@Override
public void doLayout() {
TableColumn col = getColumnModel().getColumn(0);
for (int row = 0; row < getRowCount(); row++) {
Component c = prepareRenderer(col.getCellRenderer(), row, 0);
if (c instanceof JTextArea) {
JTextArea a = (JTextArea) c;
int h = getPreferredHeight(a) + getIntercellSpacing().height;
if (getRowHeight(row) != h) {
setRowHeight(row, h);
}
}
}
super.doLayout();
} //http://tips4java.wordpress.com/2008/10/26/text-utilities/
private int getPreferredHeight(JTextComponent c) {
Insets insets = c.getInsets();
View view = c.getUI().getRootView(c).getView(0);
int preferredHeight = (int) view.getPreferredSpan(View.Y_AXIS);
return preferredHeight + insets.top + insets.bottom;
}
};
table.setEnabled(false);
table.setShowGrid(false);
table.setTableHeader(null);
table.getColumnModel().getColumn(0).setCellRenderer(new TextAreaCellRenderer());
JScrollPane sp = new JScrollPane(table);
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
JPanel p = new JPanel(new BorderLayout());
p.add(sp);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new AutoWrapTest().makeUI());
f.setSize(200, 200);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {
private static final long serialVersionUID = 1L;
private final Color evenColor = new Color(230, 240, 255);
public TextAreaCellRenderer() {
super();
setLineWrap(true);
setWrapStyleWord(true);
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(table.getBackground());
setBackground((row % 2 == 0) ? evenColor : getBackground());
}
setFont(table.getFont());
setText((value == null) ? "" : value.toString());
return this;
}
}
于 2012-04-24T22:24:38.693 に答える