Нам нужно CellEditor
для JTable
для редактирования большого многострочного текста.
Мы попытались использовать всплывающее окно, визуально расширяющее TableCell
, которое перекрывало ячейки справа и снизу. Это приводило к различным проблемам, если ячейка находилась в правом нижнем углу, около границ экрана и т. Д.
Затем мы решили использовать модальный JDialog
для редактирования значения ячейки. Таким образом, пользователи могли перемещать диалог, и мы могли сохранять его размер и положение.
Теперь проблемы начались ;-)
Мы не можем "перенаправить" первый набранный символ в диалог.
Существует много примеров переполнения стека, где эта проблема решается для пользовательских CellEditor
s, которые отображаются непосредственно в таблице (ячейке), например, здесь: Потеря первого символа в редакторе ячеек на основе панели JTable
Следующий SSCCE (из ответа camickrs: https://stackoverflow.com/a/3591230/361227) показывает, что первое нажатие клавиши во втором TableColumn теряется большую часть времени.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
/**
* Example taken from this answer: https://stackoverflow.com/a/3591230/361227
*
* @author camickr
*/
public class TablePopupEditor extends DefaultCellEditor
{
private PopupDialog popup;
private String currentText = "";
private JButton editorComponent1;
public TablePopupEditor()
{
super( new JTextField() );
setClickCountToStart( 2 );
// Use a JButton as the editor component
editorComponent1 = new JButton();
editorComponent1.setBackground( Color.white );
editorComponent1.setBorderPainted( false );
editorComponent1.setContentAreaFilled( false );
// Set up the dialog where we do the actual editing
popup = new PopupDialog();
}
@Override
public Object getCellEditorValue()
{
return currentText;
}
@Override
public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column )
{
SwingUtilities.invokeLater( new Runnable()
{
@Override
public void run()
{
System.out.println( "run" );
popup.setText( currentText );
Point p = editorComponent1.getLocationOnScreen();
popup.setLocation( p.x, p.y + editorComponent1.getSize().height );
popup.setVisible( true );
fireEditingStopped();
}
} );
currentText = value.toString();
editorComponent1.setText( currentText );
return editorComponent1;
}
/*
* Simple dialog containing the actual editing component
*/
class PopupDialog extends JDialog implements ActionListener
{
private JTextArea textArea;
public PopupDialog()
{
super( (Frame) null, "Change Description", true );
textArea = new JTextArea( 5, 20 );
textArea.setLineWrap( true );
textArea.setWrapStyleWord( true );
KeyStroke keyStroke = KeyStroke.getKeyStroke( "ENTER" );
textArea.getInputMap().put( keyStroke, "none" );
JScrollPane scrollPane = new JScrollPane( textArea );
getContentPane().add( scrollPane );
JButton cancel = new JButton( "Cancel" );
cancel.addActionListener( this );
JButton ok = new JButton( "Ok" );
ok.setPreferredSize( cancel.getPreferredSize() );
ok.addActionListener( this );
JPanel buttons = new JPanel();
buttons.add( ok );
buttons.add( cancel );
getContentPane().add( buttons, BorderLayout.SOUTH );
pack();
getRootPane().setDefaultButton( ok );
}
public void setText( String text )
{
textArea.setText( text );
}
/*
* Save the changed text before hiding the popup
*/
@Override
public void actionPerformed( ActionEvent e )
{
if ( "Ok".equals( e.getActionCommand() ) )
{
currentText = textArea.getText();
}
textArea.requestFocusInWindow();
setVisible( false );
}
}
public static void main( String[] args )
{
String[] columnNames = { "Item", "Description" };
Object[][] data =
{ { "Item 1", "Description of Item 1" }, { "Item 2", "Description of Item 2" }, { "Item 3", "Description of Item 3" } };
JTable table = new JTable( data, columnNames );
table.getColumnModel().getColumn( 1 ).setPreferredWidth( 300 );
table.setPreferredScrollableViewportSize( table.getPreferredSize() );
JScrollPane scrollPane = new JScrollPane( table );
// Use the popup editor on the second column
TablePopupEditor popupEditor = new TablePopupEditor();
table.getColumnModel().getColumn( 1 ).setCellEditor( popupEditor );
JFrame frame = new JFrame( "Popup Editor Test" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( scrollPane );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
Есть ли надежный способ поймать первого персонажа?