Problem mit RowSorter

  • Themenstarter Themenstarter gast
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

gast

Gast
Hallöchen.

Seit Java 1.6 gibts ja diesen netten RowSorter, mit dem man den Inhalt ein JTable filtern kann.

Ich benutze dafür einen regulären Ausdruck. Das Ziel ist, zb. aus einer Tabelle mit Einträge von 0-600 alles von 200-399 rauszufiltern, also nicht anzuzeigen.

Das gute ist, es funktioniert!
Hab mir diesen regulären Ausdruck gebastelt
Code:
(^[0-9]{1,2}$)|([01456789][0-9][0-9])

Mit einem Radiobutton kann man die Filterung ein bzw. aus stellen.

Das lustige kommt aber jetzt erst. Manchmal filtert der, manchmal nicht. Das ist einfach nicht reproduzierbar für mich. Starte ich mein Programm so klappt es manchmal das zu filtern, manchmal filtert der aber einfach nicht, obwohl der filter gesetzt wird!

Hat jemand Erfahrungen damit?
 
aber gern 🙂
das hier ist die methode, welche aufgerufen wird, sobald an den radiobuttons was geändert wird, (also die tabelle gefiltert werden soll)

Code:
public void setFilterForChannelTable(){
		sorter.setRowFilter(RowFilter.regexFilter(new String(".*")));
		
		
		
		String regex = ".*";
		if (selectedRow != -1 && sortSelectedModeRadioButton.isSelected()){
			// eine zeile ausgewählt, also berücksichtigen
			// regexp: hier wird kontrolliert, ob das letzte zeichen gleich der gerade ausgewählten zeile ist
			  regex = new String("("+selectedRow + "$)");
			  sorter.setRowFilter(RowFilter.regexFilter(regex));
		}
		if (satChannelsDisabledRadioButton.isSelected()){
			bar.setSatChannelsDisabled(true);
			// hmpf 
		
			// ja klappt!!!
			// von hinten: alles von 0-999 ausser 2-3 an der ersten stelle
			// der vordere ausdruckt: alle zahlen von 0-99 und nichts vor und danach
			regex = "(^[0-9]{1,2}$)|([01456789][0-9][0-9])";
			sorter.setRowFilter(RowFilter.regexFilter(regex));
		
			
			
			// hier muss jetzt noch zusätzlich nach der ausgewählten zeile gefiltert werden
			if (sortSelectedModeRadioButton.isSelected() && selectedRow != -1){
				//regex = "(^"+selectedRow+"$)|(^[01456789]{1,2}"+selectedRow+"$)|([01456789][0-9]"+selectedRow+"$)";
				regex = "(^"+selectedRow+"$)|(^[0-9&&[^23]][0-9]?"+selectedRow+"$)|(^[0-9]"+selectedRow+"$)|([01456789][0-9]"+selectedRow+"$)";
				sorter.setRowFilter(RowFilter.regexFilter(regex));
			}
		}
		else {
			bar.setSatChannelsDisabled(false);
		}

			
		
		
		System.out.println(regex);
		channelTable.revalidate();
		System.out.println(channelTable.getRowCount());
		
	}
 
nur so als Tipp:
fange mit einem einfachen Pattern an (a la 'erste Zahl eine 3')

wenn es damit auch schon Probleme gibt, dann ist zumindest der Code DEUTLICH einfacher,
ansonsten Schritt für Schritt den RegEx erweitert, bis du genau weißt, welcher Teil stört
 
es liegt NICHT an den regulären ausdrücken. die funktionieren sicher. mittlerweile hab ich noch was mehr rumgespielt und dieser rowsorter hat wirklich irgendwo nen knacks. manchmal filtert er, manchmal nicht.


manchmal filtert er genauso wie ich das will, manchmal filtert er nicht alles. scheiss ding.
 
nochmal was von mir, für die, die nicht glauben das die regexp richtig sind.

die müssen richtig sein. weil manchmal filtert der das ja genau wie ich will. wenn der regexp falsch wäre würde das ja nicht gehen, oder?
 
Schwachsinn, drastisch ausgedrückt,
denn deine RegExp ändert sich ja, manchmal ist 'selectedRow' mit drin,
außerdem könnten sich die Daten ändern, was von hier aus überhaupt nicht zu überblicken ist,

also kannst du niemanden 100% überzeugen, dass die RegExp richtig ist

----------

das aber nur am Rande, war nur ein minimaler Hinweis von mir,
ich glaube gerne, dass der RegExp richtig ist, man kann noch genug anderes falsch machen
 
SlaterB hat gesagt.:
Schwachsinn, drastisch ausgedrückt,
denn deine RegExp ändert sich ja, manchmal ist 'selectedRow' mit drin,
außerdem könnten sich die Daten ändern, was von hier aus überhaupt nicht zu überblicken ist,

also kannst du niemanden 100% überzeugen, dass die RegExp richtig ist

----------

das aber nur am Rande, war nur ein minimaler Hinweis von mir,
ich glaube gerne, dass der RegExp richtig ist, man kann noch genug anderes falsch machen


wenn man keine ahnung hat...
 
lange habt ihr drauf gewartet, hier meine demo

Code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import java.util.List;

import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableRowSorter;





public class testFrame extends JFrame {

	private JPanel panel;
	private JTable  channelTable;
	private channelTableModel channelModel;
	private JScrollPane channelScrollpane;
	private TableRowSorter sorter;
	private JCheckBox sort;
	
	testFrame(){
		
		
		
		panel = new JPanel();
		
		add(panel);
		
		
		channelModel = new channelTableModel();
		channelTable = new JTable(channelModel);
		channelTable.setName("channel");
		channelScrollpane = new JScrollPane(channelTable);
		channelTable.setPreferredScrollableViewportSize(new Dimension(500,300));
		channelTable.setDefaultRenderer(String.class,new CenterAlignmentCellRenderer());
		channelTable.setDefaultRenderer(JRadioButton.class,new CenterAlignmentCellRenderer());
		panel.add(channelScrollpane);
		
		
		
		sorter = new TableRowSorter(channelModel);
		channelTable.setRowSorter(sorter);
		
		
		channelTable.getColumn("allowed").setCellRenderer(new RadioButtonRenderer());
		channelTable.getColumn("allowed").setCellEditor(new RadioButtonEditor(new JCheckBox()));
		channelTable.getColumn("not recommended").setCellRenderer(new RadioButtonRenderer());
		channelTable.getColumn("not recommended").setCellEditor(new RadioButtonEditor(new JCheckBox()));
		channelTable.getColumn("not allowed").setCellRenderer(new RadioButtonRenderer());
		channelTable.getColumn("not allowed").setCellEditor(new RadioButtonEditor(new JCheckBox()));
		
		/**
		 * Der hier ist wichtig, da sonst die radiobuttons nicht richtig aktualsisiert werden
		 */
		
		channelTable.addMouseListener(new MouseListener(){
			public void mouseClicked(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {}
			public void mouseReleased(MouseEvent e) {
				channelTable.repaint();
				/*if (selectedRow != -1){
					//analyzeChannelTableAndSetModeTable(String.valueOf(selectedRow));
				}*/
				
			}
		});
		

		
		

		
		for (int x = 0; x <= 600; x++){
			channelModel.addEntry(x, String.valueOf(x), new JRadioButton("",getRandomEntry()), new JRadioButton("",getRandomEntry()), new JRadioButton("",getRandomEntry()));
		}
		
		for (int i = 0; i <= 600; i++){
			ButtonGroup group1 = new ButtonGroup();
			
			((JRadioButton)channelModel.getValueAt(i,1)).setBackground(Color.WHITE);
			((JRadioButton)channelModel.getValueAt(i,2)).setBackground(Color.WHITE);
			((JRadioButton)channelModel.getValueAt(i,3)).setBackground(Color.WHITE);
			
			
			group1.add((JRadioButton)channelModel.getValueAt(i,1));
			group1.add((JRadioButton)channelModel.getValueAt(i,2));
			group1.add((JRadioButton)channelModel.getValueAt(i,3));
			//group1.add((JRadioButton)modeModel.getValueAt(i,4));
		}
		
	
		
		sort = new JCheckBox("filtern");
		sort.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				setFilterForChannelTable(sort.isSelected());
				
			}
			
		});
		
		panel.add(sort);
		
	}
	public void setFilterForChannelTable(boolean b){
		sorter.setRowFilter(RowFilter.regexFilter(new String(".*")));
		
		
		System.out.println(b);
		
		String regex = ".*";
		
		if (b){
			regex = "(^[0-9]{1,2}$)|([01456789][0-9][0-9])";
		}
		else {
			regex = ".*";
		}
		
		sorter.setRowFilter(RowFilter.regexFilter(regex));
		
		
		System.out.println(regex);

		System.out.println("Einträge übrig: " +channelTable.getRowCount());
		
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		testFrame test = new testFrame();
		test.setVisible(true);

	}

	
	
	public boolean getRandomEntry(){
		//System.out.println((Math.random() > 0.5)? "X":"");
		return (Math.random() > 0.5)? false:true;
	}
	
}


class channelTableModel extends AbstractTableModel {
	private String[] columnNames = { "no", "allowed", "not recommended", "not allowed"};

	private List data = new LinkedList<Object[][]>();

	public int getColumnCount() {
		return columnNames.length;
	}

	public int getRowCount() {
		return data.size();
	}

	public String getColumnName(int col) {
		return columnNames[col];
	}

	public Object getValueAt(int row, int col) {
		Object[] value = (Object[]) data.get(row);
		return value[col];
	}

	public void removeEntry(int row) {
		data.remove(row);
		fireTableDataChanged();
	}
	
	public void removeAll() {
		data.clear();
		fireTableDataChanged();
	}

	public void addEntry(int row, String number, JRadioButton allowed, JRadioButton not_recommended, JRadioButton not_allowed) {
		data.add(row, new Object[] { number, allowed, not_recommended, not_allowed});

		fireTableDataChanged();
	}

	public void editEntry(int row, int col, Object newvalue) {
		if (row >= 0) {
			Object[] value = (Object[]) data.get(row);
			value[col] = newvalue;
			data.set(row, value);
			fireTableDataChanged();
		}
	}

	public Class getColumnClass(int c) {
		return getValueAt(0, c).getClass();
	}

	/*
	 * Don't need to implement this method unless your table's editable.
	 */
	public boolean isCellEditable(int row, int col) {
		// Note that the data/cell address is constant,
		// no matter where the cell appears onscreen.
		if (col >= 1 && col <= 4) {
			return true;
		} else {
			return false;
		}
	}
	
	
	
	

}class CenterAlignmentCellRenderer extends DefaultTableCellRenderer {
	Color uneditable = new Color(238, 238, 238);
	
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
			boolean hasFocus, int row, int column) {
		Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
		
		if (table.getName().equals("mode")){
			if (column == 0 | column ==  4) {
				cell.setBackground(uneditable);
			}
			else {
				cell.setBackground(Color.white);
			}
		}
		else if (table.getName().equals("channel")){
			if (column == 0){
				cell.setBackground(uneditable);
			}
			else {
				cell.setBackground(Color.white);
			}
		}
		
		((JLabel) cell).setHorizontalAlignment(SwingConstants.CENTER);	
			
		

		return cell;

	}

}


Also mit der checkbox künnt ihr die filtern aktivieren bzw. deaktivieren. gibt auch nen paar system.out ausgaben.

wahrscheinlich wird es beim ersten versuch richtig filtern. also programm wieder schliessen, neu starten und nochmal probieren.
beim 2ten oder dritten mal klappts dann wieder nicht.

das ist wirklich verzwickt!
 
ach ja nochwas. wenn man das programm gestartet hat und der filtert richtig, dann tut der das immer.

wenn man das programm startet und der das filtern nicht hinkriegt, dann schafft der das nie. man muss also immer neu starten zum testen.
 
hehe,

das hat nun fast ne Stunde gedauert, aber war's mir wert,

ohne Ahnung habe ich den Fehler gefunden,
(Ursache übrigens 'geänderte Daten')

mal überlegen ob ich dir das noch verrate,
ist wirklich sehr gut versteckt..
 
ja dann erzähl mal!

kann ja jeder sagen er hätte das problem gefunden 🙂
 
ich sehe, dass dir auch diese Gelegenheit zur Entschuldigung egal ist..
 
.oO( och jetzt flenn nicht rum. bist ja wie nen mädchen.)


"Oh ja grosser meister slater b, ich bin unwürdig, aber verzeihen sie mir bitte?
 
die Unterwürfigkeit kommt schon gut rüber, fehlt noch wahre Reue dazu 😉

aber ich bin ja im Gegensatz zu dir kein Unmensch, 2 Tipps:

1.) RowSorter schaut sich die ganze Row an, auch die Buttons
2.) RowSorter schaut sich (anscheinend) nicht das an was in der Tabelle zu sehen ist,
sondern object.toString()
 
SlaterB hat gesagt.:
die Unterwürfigkeit kommt schon gut rüber, fehlt noch wahre Reue dazu 😉

aber ich bin ja im Gegensatz zu dir kein Unmensch, 2 Tipps:

1.) RowSorter schaut sich die ganze Row an, auch die Buttons
2.) RowSorter schaut sich (anscheinend) nicht das an was in der Tabelle zu sehen ist,
sondern object.toString()


Bist du sicher, dass deine Lösung funktioniert? Hast du das mehr als einmal ausprobiert?

Daran hatte ich auch schon gedacht. Nur die Tatsache, dass der Filter ja manchmal genauso funktioniert wie er soll hat mich davor abgehalten.
 
weil toString() eben bei jedem Start was anderes liefert (anschauen..)
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben