¿Cómo pintar el Dropline de un RowHeader-JTable en el Main-JTable durante un DragAndDrop?

bobndrew:

Estoy usando una segunda JTable en la ventana gráfica de un JScrollPane para construir un RowHeader para una tabla principal. DragAndDrop en la tabla principal está deshabilitado. En la tabla de encabezado de fila, DnD está habilitado.

Si el usuario inicia un Arrastrar en el encabezado de fila, quiero extender la línea desplegable del encabezado de fila pintado (la línea negra en la imagen) sobre la tabla principal (como la línea verde en la imagen).

línea de derivación para el mantenible

¿Alguien tiene algún consejo para mí?
Aquí está el SSCCE:

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.DropMode;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;


public class DNDLinePainterExampleMain extends JFrame {

  public DNDLinePainterExampleMain() {
    JTable mainTable = new JTable(4, 3);
    mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

    JTable rowTable = new RowHeaderTable(mainTable);
    rowTable.setAutoscrolls(true);
    rowTable.setDragEnabled(true);
    rowTable.setTransferHandler(new RowHeaderTransferHandler());
    rowTable.setDropMode(DropMode.INSERT_ROWS);

    JScrollPane scrollPane = new JScrollPane(mainTable);
    scrollPane.setRowHeaderView(rowTable);
    scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
        rowTable.getTableHeader());
    this.add(scrollPane);
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        JFrame f = new DNDLinePainterExampleMain();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
      }
    });
  }


  /*
   * Use a JTable as a renderer for row numbers of a given main table. This
   * table must be added to the row header of the scrollpane that contains the
   * main table. from:
   * http://tips4java.wordpress.com/2008/11/18/row-number-table/
   */
  public class RowHeaderTable extends JTable implements ChangeListener,
      PropertyChangeListener {

    private final JTable table;

    public RowHeaderTable(JTable table) {
      this.table = table;
      table.addPropertyChangeListener(this);

      setFocusable(false);
      setAutoCreateColumnsFromModel(false);

      updateRowHeight();
      updateModel();
      updateSelectionModel();

      TableColumn column = new TableColumn();
      column.setHeaderValue("");
      addColumn(column);
      column.setCellRenderer(new RowNumberRenderer());

      getColumnModel().getColumn(0).setPreferredWidth(50);
      setPreferredScrollableViewportSize(getPreferredSize());

      getTableHeader().setReorderingAllowed(false);
    }

    @Override
    public void addNotify() {
      super.addNotify();
      Component c = getParent();
      // Keep scrolling of the row table in sync with the main table.
      if (c instanceof JViewport) {
        JViewport viewport = (JViewport) c;
        viewport.addChangeListener(this);
      }
    }

    /*
     * Delegate method to main table
     */
    @Override
    public int getRowCount() {
      return table.getRowCount();
    }

    @Override
    public int getRowHeight(int row) {
      return table.getRowHeight(row);
    }

    /*
     * This table does not use any data from the main TableModel, so just return
     * a value based on the row parameter.
     */
    @Override
    public Object getValueAt(int row, int column) {
      return Integer.toString(row + 1);
    }

    /*
     * Don't edit data in the main TableModel by mistake
     */
    @Override
    public boolean isCellEditable(int row, int column) {
      return false;
    }

    // implements ChangeListener
    @Override
    public void stateChanged(ChangeEvent e) {
      // Keep the scrolling of the row table in sync with main table
      JViewport viewport = (JViewport) e.getSource();
      JScrollPane scrollPane = (JScrollPane) viewport.getParent();
      scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
    }

    // implements PropertyChangeListener
    @Override
    public void propertyChange(PropertyChangeEvent e) {
      // Keep the row table in sync with the main table
      if ("rowHeight".equals(e.getPropertyName()))
        updateRowHeight();

      if ("selectionModel".equals(e.getPropertyName()))
        updateSelectionModel();

      if ("model".equals(e.getPropertyName()))
        updateModel();
    }

    private void updateRowHeight() {
      setRowHeight(table.getRowHeight());
    }

    private void updateModel() {
      setModel(table.getModel());
    }

    private void updateSelectionModel() {
      setSelectionModel(table.getSelectionModel());
    }


    /*
     * Borrow the renderer from JDK1.4.2 table header
     */
    private class RowNumberRenderer extends DefaultTableCellRenderer {

      public RowNumberRenderer() {
        setHorizontalAlignment(JLabel.CENTER);
      }

      @Override
      public Component getTableCellRendererComponent(JTable table,
          Object value, boolean isSelected, boolean hasFocus, int row,
          int column) {
        if (table != null) {
          JTableHeader header = table.getTableHeader();

          if (header != null) {
            setForeground(header.getForeground());
            setBackground(header.getBackground());
            setFont(header.getFont());
          }
        }

        if (isSelected) {
          setFont(getFont().deriveFont(Font.BOLD));
        }

        setText((value == null) ? "" : value.toString());
        setBorder(UIManager.getBorder("TableHeader.cellBorder"));

        return this;
      }
    }//class RowNumberRenderer

  }//class RowHeaderTable


  public class RowHeaderTransferHandler extends TransferHandler {

    @Override
    public int getSourceActions(JComponent c) {
      return COPY_OR_MOVE;
    }

    @Override
    protected Transferable createTransferable(JComponent c) {
      return new StringSelection(c.getName());
    }

    @Override
    public boolean canImport(TransferSupport supp) {
      return true;
    }
  }//class RowHeaderTransferHandler


}//class DNDLinePainterExampleMain
Xeon:

Te sugiero que hagas esto (usando la funcionalidad de arrastrar y soltar de Swing):

    RowHeaderTable rowTable = new RowHeaderTable(mainTable);
    rowTable.setAutoscrolls(true);
    rowTable.setDragEnabled(true);
    rowTable.setTransferHandler(new RowHeaderTransferHandler(mainTable));
    rowTable.setDropMode(DropMode.INSERT_ROWS);
    try {
        DropTarget dropTarget = rowTable.getDropTarget();
        dropTarget.addDropTargetListener(rowTable);
    }
    catch(TooManyListenersException e) {
        e.printStackTrace();
    }

Ahora tienes que implementar DropTargetListener:

public class RowHeaderTable extends JTable implements ChangeListener, PropertyChangeListener, DropTargetListener {

Estos son 2 métodos que deberían interesarle:

    @Override
    public void dragEnter(DropTargetDragEvent dtde) { shouldPaint = true }

    @Override
    public void dragExit(DropTargetEvent dte) { shouldPaint = false }

Ahora debes manipular tu mainTable(para pintar esta "línea verde") usando tu TranserHandler:

    @Override
    public boolean canImport(TransferSupport supp) {
        DropLocation location = supp.getDropLocation();
        if(location instanceof javax.swing.JTable.DropLocation && shouldPaint) {
            javax.swing.JTable.DropLocation tableLocation = (javax.swing.JTable.DropLocation) location;
            int rowToInsert = tableLocation.getRow();
            //paint somehow the "green line"
            //remember that canImport is invoked when you move your mouse
        }
        return true;
    }

Básicamente, debe implementar su propio renderizador de filas o algo similar (como en la respuesta de @naugler). De alguna manera también debería proporcionar boolean shouldPainta su TransferHandler. Pero esto no es gran cosa de implementar.

Espero que esto ayude.

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

Cómo averiguar la excepción durante el uso de un PrintStream en Java

¿Cómo puedo cambiar el tamaño de un JScrollPane con JTable en él?

hacer doble clic en un ícono de imagen en jtable hace que el ícono de imageIcon desaparezca

JTable en JScrollPane, ¿cómo configurar el fondo?

¿Cómo puedo poner un control en el JTableHeader de un JTable?

¿Cómo obtener de manera confiable el índice de fila en JTable desde MouseEvent?

eliminar el borde de las celdas en un jtable

¿Cómo realizar un seguimiento del índice de filas cuando el usuario ha ordenado JTable?

Cómo hacer JTable en cellchange seleccionar todo el texto

¿Cómo puedo obtener el valor de celda mostrado en un JTable (no el valor completo de TableModel)?

Cómo ocultar un UIButton durante el desplazamiento de TextView

Cómo pintar el icono de información de Windows estándar de forma agradable en el índice de la pestaña de un control de página

¿Cómo cambiar el texto de una etiqueta durante un bucle for en IOS swift4?

¿Cómo actualizar dinámicamente un JTable basado en los valores de JComboBox que se encuentran en el mismo JPanel en Java?

Pintar el fondo de un QTableView (con un QStyledItemDelegate personalizado)

Cómo leer un valor en dockerfile durante el tiempo de ejecución

¿Cómo actualizar dinámicamente un JTable basado en los valores de JComboBox que se encuentran en el mismo JPanel en Java?

Guardar datos en un nuevo JTable (nuevo JFrame) usando el constructor de GUI de NetBeans

Visualización de un icono adicional en el lado izquierdo de un encabezado de columna JTable (Nimbus)

resultado de búsqueda en un JTable

¿Cómo establecer el enfoque en varias filas en Jtable?

¿Hay alguna forma de seleccionar todo el texto en una celda en un JTable sin un CellEditor?

¿Cómo conocer los parámetros de un método en javascript durante el desarrollo?

¿Cómo ignorar una columna de un TableModel en un JTable?

¿Cómo verificar un campo adicional durante el inicio de sesión en Laravel?

cómo exportar el contenido de un jTable filtrado a un pdfpTable

cómo exportar el contenido de un jTable filtrado a un pdfpTable

¿Cómo registrar los valores de un tensor durante el entrenamiento en Keras?

En una JTable cuando selecciono un valor de la fila, me muestra el valor anterior