Sortowanie tabeli i widoku

0

Witam.
Obczajam sobie komponent jtable. I pisząc jakiś tam program z przykładów napotkałem na pewien problem a dokładnie problemy.
Prosiłbym zatem w miarę możliwości o pomoc.
Mój model wygląda tak:

package testy;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

class SampleSortingTableModel extends AbstractTableModel implements TableModelListener  {
  protected TableModel base;

  protected int sortColumn;

  protected int[] row;

  public SampleSortingTableModel(TableModel tm, int sortColumn) {
    this.base = tm;
    this.sortColumn = sortColumn;
    tm.addTableModelListener(this);
    rebuild();
  }

  public Class getColumnClass(int c) {
    return base.getColumnClass(c);
  }

  public int getColumnCount() {
    return base.getColumnCount();
  }

  public String getColumnName(int c) {
    return base.getColumnName(c);
  }

  public int getRowCount() {
    return base.getRowCount();
  }

  public Object getValueAt(int r, int c) {
    return base.getValueAt(row[r], c);
  }

  public boolean isCellEditable(int r, int c) {
    return base.isCellEditable(row[r], c);
  }

  public void setValueAt(Object value, int r, int c) {
    base.setValueAt(value, row[r], c); // Notification will cause re-sort
  }

  public void tableChanged(TableModelEvent event) {
	fireTableDataChanged();	
  }

  protected void rebuild() {
    int size = base.getRowCount();
    row = new int[size];
    for (int i = 0; i < size; i++) {
      row[i] = i;
    }
    sort();
  }

  protected void sort() { // Sort and notify listeners
    for (int i = 1; i < row.length; i++) {
      int j = i;
      while (j > 0 && compare(j - 1, j) > 0) {
        int temp = row[j];
        row[j] = row[j - 1];
        row[j - 1] = temp;
        j--;
      }
    }
    fireTableStructureChanged();
  }

  protected int compare(int i, int j) {
    String s1 = base.getValueAt(row[i], sortColumn).toString();
    String s2 = base.getValueAt(row[j], sortColumn).toString();
    return s1.compareTo(s2);
  }


}

Natomiast program wygląda tak:

package testy;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.nio.channels.spi.SelectorProvider;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class SortableTableModelAbstractTableModel extends JFrame implements ListSelectionListener{
	  DefaultTableModel model = new DefaultTableModel(new Object[][] { { "this", "1" },
	      { "text", "2" }, { "will", "3" }, { "be", "4" }, { "sorted", "5" } }, new Object[] {
	      "Column 1", "Column 2" });

	  private JTable tableOrig, tableSorted;
	  public SortableTableModelAbstractTableModel() {
	    setDefaultCloseOperation(EXIT_ON_CLOSE);
	    tableOrig = new JTable(model);
	    tableOrig.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
	    tableSorted = new JTable(new SampleSortingTableModel(model, 0));
	    tableSorted.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
	    JPanel panel = new JPanel(new GridLayout(1, 2));
	    panel.add(new JScrollPane(tableOrig));
	    panel.add(new JScrollPane(tableSorted));
	    getContentPane().add(panel, BorderLayout.CENTER);
	    pack();
	    tableOrig.getSelectionModel().addListSelectionListener(this);
	    tableOrig.setAutoCreateRowSorter(true);
   	    
	  }

	  public static void main(String arg[]) {
	    new SortableTableModelAbstractTableModel().setVisible(true);
	  }

	@Override
	public void valueChanged(ListSelectionEvent arg0) {
		// TODO Auto-generated method stub
		String selectedData = null;
		int[] selectedRows = tableOrig.getSelectedRows();
		int[] selectedColumns = tableOrig.getSelectedColumns();
		for (int i = 0; i < selectedRows.length; i++) {
	          for (int j = 0; j < selectedColumns.length; j++) {
	          
	        	 selectedData = (String) tableOrig.getValueAt(selectedRows[i], selectedColumns[j]);
	      	         System.out.println("zaznaczony wiersz w tabeli: " + selectedData);
	      		 System.out.println("Wartosc w modelu: "+(String)tableOrig.getModel().getValueAt(selectedRows[i], selectedColumns[j]));
                         System.out.println("######################################");
	      		
	          }
	        }	
	}	
}

I teraz moje problemy a raczej pytania:).

  1. Mam problem z sortowanie po kolumnach tzn sprawa wygląda tak że jeżeli zmienię wartość w tabeli np z 3 na 30 ( klikając na komórkę i wpisując nową wartość ) to w modelu ta wartość się zmienia , w tabeli też, ale podczas sortowania nie brana jest pod uwagę ( tzn klikając na kolumnę sortuję mi ją tak jak by wartość dalej była 3 a nie 30 ). Nie mam pojęcia dlaczego.
  2. Chodzi mi o myszkę jeżeli kursorami poruszam się po tabeli to wyświetla mi po każdym naciśnięciu klawisza tylko raz wartość rekordu , czyli tak jak powinno. Natomiast w przypadku kliknięcia w komórkę, wartość rekordu wyświetlana jest dwa razy. Przypuszczam że to dlatego że kliknięcie myszki to pewnie dwie akcje czyli wciśnięcie klawisza i puszczenie klawisza i dla każdej z tej akcji wywoływana jest funkcja :
    public void valueChanged(ListSelectionEvent arg0)
    czy da się to zmienić czy tak ma być i muszę to zaakceptować ( oczywiście wiem że jest to słuszne rozdzielnie tych dwóch zdarzeń ale w tym przypadku jest mi to nie potrzebne).
  3. I ostatnie pytanie ( pewnie równie lamerskie jak dwa poprzednie). Chciałbym testowo w funkcji modelu:
    public void tableChanged(TableModelEvent event)
    wywołać sortowanie tabeli ( to samo co się robi zaraz po starcie programu ) jednak kiedy wywołam tą funkcję ( metodę) rebuild nic się nie dzieje tzn nie widzę żeby tabela została posortowana ( chodzi o widok) . Czy w jakiś sposób muszę odświeżyć ten widok ? Wywołanie funkcji tableOrgi.repaint() nic nie zmienia.
    Pozdrawiam
0
  1. Przecież zmiana "3" na "30" nie zmienia kolejności, "30" jest po "2" i przed "4".
  2. Wykorzystaj metodę zdarzenia e
e.getValueIsAdjusting()

pozwala rozróżnić wciśnięcie i puszczenie.

0
bogdans napisał(a):
  1. Przecież zmiana "3" na "30" nie zmienia kolejności, "30" jest po "2" i przed "4".
    .

Czyli rozumiem że w tabeli wszystko jest tekstem dlatego tak to jest sortowane.

0

W Twojej tabeli tak, w dowolnej nie.

0

Dzięki za pomoc.
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1