varias una seleccionar seleccionada seleccion quitar primera pasar otro obtener los formulario filas fila desde datos como codigo java swing jtable jscrollpane

java - seleccionada - seleccionar una fila de un jtable desde codigo



¿Cómo puedo congelar una selección de fila JTable dentro de un panel de desplazamiento? (2)

Bien, este me molestaba mucho, así que dediqué un tiempo para encontrar una forma de hacerlo. Encontré dos opciones:

  1. El que prefiero porque me resulta mucho más simple: bloquear las nuevas entradas en el modelo de tabla y almacenarlas en un búfer. Cada vez que descongelamos, lavamos el buffer en el modelo de la mesa.
  2. La segunda opción consiste en ubicar la fila visible superior actual. Si el usuario se desplaza, capturamos la fila visible superior. A medida que el modelo se actualiza, ubicamos la fila capturada en la tabla y establecemos la posición del puerto de visualización para eso.

Aquí hay un SSCCE que ilustra ambos mecanismos (no importa la locura del diseño del código, probé un montón de cosas, extender el JScrollPane en realidad no es una buena idea, todo puede hacerse externamente).

import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.Vector; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.DefaultTableModel; public class Tables { private static class JScrollPaneExtension extends JScrollPane implements TableModelListener, AdjustmentListener { private boolean frozen = false; private Vector<String> rowData; private final JTable table; private final MyTableModel tableModel; private JScrollPaneExtension(JTable table, MyTableModel tableModel) { super(table); this.table = table; this.tableModel = tableModel; tableModel.addTableModelListener(this); getVerticalScrollBar().addAdjustmentListener(this); } public boolean isFrozen() { return frozen; } public void setFrozen(boolean frozen) { if (frozen != this.frozen) { this.frozen = frozen; if (frozen) { captureCurrentTopRowData(); } else { rowData = null; } } } private void captureCurrentTopRowData() { int row = table.rowAtPoint(getViewport().getViewPosition()); if (row > -1) { rowData = (Vector<String>) tableModel.getDataVector().get(row); } } @Override public void adjustmentValueChanged(AdjustmentEvent e) { if (frozen) { captureCurrentTopRowData(); scrollToRowData(); } } @Override public void tableChanged(TableModelEvent e) { scrollToRowData(); } private void scrollToRowData() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (frozen) { int index = tableModel.getDataVector().indexOf(rowData); getViewport().setViewPosition(table.getCellRect(index, 0, true).getLocation()); } } }); } } public static class MyTableModel extends DefaultTableModel { private int count; private boolean frozen = false; private List<Vector<String>> buffer = new ArrayList<Vector<String>>(); public MyTableModel() { addColumn("Test"); } public void insertNewRow() { Vector<String> rowData = createNewRowData(); if (isFrozen()) { buffer.add(rowData); } else { insertRow(0, rowData); } } private Vector<String> createNewRowData() { Vector<String> data = new Vector<String>(1); data.add("Hello-" + (count++)); return data; } public boolean isFrozen() { return frozen; } public void setFrozen(boolean frozen) { if (frozen == this.frozen) { return; } this.frozen = frozen; if (!frozen) { flushBuffer(); } } private void flushBuffer() { for (Vector<String> rowData : buffer) { insertRow(0, rowData); } } } public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final MyTableModel model = new MyTableModel(); JTable table = new JTable(model); final JScrollPaneExtension scroll = new JScrollPaneExtension(table, model); JPanel panel = new JPanel(); final JButton freeze = new JButton("Freeze"); freeze.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { if (model.isFrozen()) { freeze.setText("Freeze model"); } else { freeze.setText("Continue"); } model.setFrozen(!model.isFrozen()); } }); final JButton freeze2 = new JButton("Freeze scroll"); freeze2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { if (scroll.isFrozen()) { freeze2.setText("Freeze scroll"); } else { freeze2.setText("Resume scroll"); } scroll.setFrozen(!scroll.isFrozen()); } }); scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); frame.add(scroll); panel.add(freeze); panel.add(freeze2); frame.getContentPane().add(panel, BorderLayout.NORTH); frame.pack(); frame.setVisible(true); Timer t = new Timer(); t.scheduleAtFixedRate(new TimerTask() { @Override public void run() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { model.insertNewRow(); } }); } }, new Date(), 300); } }

Tengo una JTable que se actualiza con frecuencia. Se sienta dentro de un panel de desplazamiento.

Ocasionalmente, veremos un mensaje en el que nos gustaría profundizar. Desafortunadamente, debido a la cantidad de actualizaciones, el mensaje se desplazará de la pantalla visible antes de que podamos terminar de mirarlo.

Me gustaría poder congelar la ventana gráfica / desplazamiento mientras examinamos el mensaje pero aún así permitimos que el modelo de tabla se actualice con mensajes nuevos.

Puedo obtener la fila seleccionada para ir a la cima con este código:

int firstSelectedRow = table.getSelectedRow(); Rectangle rowLocation = table.getCellRect(firstSelectedRow, 0, false); scroll.getVerticalScrollBar().setValue(rowLocation.y); freezeScrolling.setText("Resume Updates");

pero eso solo ocurre al presionar un botón y luego se desplaza rápidamente.

¿Hay alguna manera de indicarle a la ventana / panel de desplazamiento que se congele en una selección y que la desactive para que el panel de desplazamiento se actualice como es de esperar?


Es posible que pueda adaptar el enfoque que se muestra aquí . Condiciona el desplazamiento basado en el valor de getValueIsAdjusting() en un AdjustmentListener . Haga clic en el pulgar para suspender el desplazamiento; liberar para reanudar.