# Actionlistener vor änderung der Selectedrow(JTable)



## weljo (22. Jul 2009)

Hi leute hab jetzt nach einigen problemen meine tabelle umgedreht was mir einiges erleichtert hat ... jetzt habe ich eine tabelle bei der edit... in der ersten spalte auf JComboBox gesetzt wurde und jede JComboBox einen Actionlistener hat .... wenn nun ein item in einer Combobox gewählt wird sollten sich die werte in der entsprechenden zeile auch ändern ... mein problem ist jetzt dass wenn ich z.b. in zeile 3 bin und auf die Combobox der Zeile 6 klick komm ich in den Actionlistener. jedoch wenn ich jetzt im actionlistener getSelectedRow aufrufe glaubt er immer noch in der 3. reihe zu sein. 

hab bereits versucht um das problem zu lösen nur darauf zu achten wenn ein anderes item in der Combobox gewählt wird indem ich nur etwas gemacht habe wenn man sich in einer anderen zeile befindet und das gewählte item sich vom uhrsprünglichen unterscheident (dabei bin ich auf den fehler draufgekommen)

und habs auch mit ItemListener versucht jedoch wird der einfach doppelt so oft wie der Actionlistener aufgerufen

hat wer eine lösung ....


----------



## Gast2 (22. Jul 2009)

Ja wahrscheinlich ist noch die falsche Zeile in deiner Tabelle makiert...

und das mit dem ItemListener ist auch logisch dass er doppelt so oft aufgerufen wird
dafür gibt es 
	
	
	
	





```
ItemEvent.SELECTED und ItemEvent.DESELECTED
```


----------



## weljo (22. Jul 2009)

ma thx für die schnelle antwort ... jedoch soweit war ich auch bereits ... nur wie kann ich das problem lösen damit ich bereits im listener die richtige zeile hab??? ( "etwas anders" ausgedrückt: wie kann ich der Tabelle vorrang vor dem listener verschaffen.)


----------



## Gast2 (22. Jul 2009)

1. Hat er im ItemListener die richtige Zeile?
2. Wird die Zeile überhaupt(visuell) irgendwann mal richtig makiert?
3. KSKB?


----------



## weljo (22. Jul 2009)

1. ItemListener selbes problem wie mit ActionListener 
2. ja wird mit freiem auge betrachtet sofort richtig markiert (aber anscheinend minimal später)
3. was ist KSKB???

man könnte das problem auch lösen indem ich wirklich nur beim ändern in der ComboBox etwas mach und nicht schon beim selectieren ... jedoch hab ich das ohne das zeilenproblem zu vermeiden nicht geschafft


----------



## Ebenius (22. Jul 2009)

Nochmal langsam: Du hast JComboBoxes als CellEditor in der JTable? Wozu rufst Du getSelectedRow() auf? Das klingt seltsam. Mach einfach mal ein kleines Beispiel-Programm!

Die Frage, wie Du die Listener zu irgendwelchem Vorrang bringst deutet deutlich darauf hin, dass Du irgendwie auf dem Holzweg gelandet bist. Listener feuern eigentlich immer in unvorhersagbarer Reihenfolge und daran sollte man nichts ändern.

KSKB: Halt mal die Maus über "KSKB" ...

Ebenius


----------



## weljo (22. Jul 2009)

also rufe es im action listener auf will in meinem container der die Daten beinhaltet etwas ändern und damit ich weis welcher index es ist brauch ich die zeile

naja kurz ist relativ 


```
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;


public class MainFrame extends javax.swing.JFrame implements  ActionListener{
	private JPanel north;
	private JPanel south;
	private JButton complete;
	private JButton add;
	private JButton createnew;
	
	public static JTable table; 
	public static Vector<Container> container;
	public static Vector<String> columnname;
	public static Vector<Vector<String>> tablecontent;
	public static TableModel tablemodel;
	
	public static Vector<Combo> combos = new Vector<Combo>(); 
	public static Vector<String> names = new Vector<String>();	
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				container = new Vector<Container>();
				container.add(new Container("H2O", "20°", "1 min", "-", "-"));
				
				names.add("R2D2");
				names.add("Shure SM 58");
				names.add("delirium");
				names.add("blabla");				
				
				MainFrame inst = new MainFrame();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public MainFrame() {
		super();
		tablecontent = new Vector<Vector<String>>();
		tablemodel = new DefaultTableModel();
		columnname = new Vector<String>();
		initGUI();
	}
	
	public static void reload()
	{		
		tablecontent.clear();
		columnname.clear();
		int z = container.size();
		
		for(int y=0; y<z ; y++)
		{
			tablecontent.add(new Vector<String>());
			for(int i=0; i<5 ; i++)				
			{
				tablecontent.lastElement().add(container.elementAt(y).getName());
				tablecontent.lastElement().add(container.elementAt(y).getTemp());
				tablecontent.lastElement().add(container.elementAt(y).getTime());
				tablecontent.lastElement().add(container.elementAt(y).getDilution());
				tablecontent.lastElement().add(container.elementAt(y).getInfo());
			}
		}
		
		columnname.add("name");
		columnname.add("temp");
		columnname.add("time");
		columnname.add("dilution");
		columnname.add("info");
		
		tablemodel = new DefaultTableModel(tablecontent, columnname);
		table.setModel(tablemodel);
		table.getColumn("name").setCellEditor(new DefaultCellEditor(new Names(names)));
	}
	
	private void initGUI() {
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			
			{
				north = new JPanel();

				getContentPane().add(north, BorderLayout.CENTER);
				{
					table = new JTable();
					north.add(table);
				}
			}			
			{
				south = new JPanel();
				getContentPane().add(south, BorderLayout.SOUTH);
				{
					createnew = new JButton();
					south.add(createnew);
					createnew.setText("new");
					createnew.addActionListener(this);
				}
				{
					add = new JButton();
					south.add(add);
					add.setText("+");
					add.addActionListener(this);
				}
				{
					complete = new JButton();
					south.add(complete);
					complete.setText("fertigstellen");
					complete.addActionListener(this);
				}
			}
			pack();
			this.setSize(588, 342);
		} catch (Exception e) {
			e.printStackTrace();
		}
		reload();
	}
	
	@Override
	public void actionPerformed(ActionEvent e) 
	{
		if(e.getSource()== createnew)
		{
			int i = JOptionPane.showConfirmDialog(null,"wenn Sie neu beginnen wollen gehen die alten Informationin verlohren. Möchten Sie vortfahren?", "Warnung", JOptionPane.YES_NO_OPTION);
			if(i == 0)
			{
				container.clear();
				container.add(new Container("H2O", "20°", "1 min", "-", "-"));
				reload();
			}
		}
		
		if(e.getSource()== add)
		{
			container.add(new Container("H2O", "20°", "1 min", "-", "-"));
			reload();
		}
	}
}
```


```
public class Combo 
{	
	String name;
	String temp;
	String time ;
	String dilution;
	long conter;
	
	public Combo(String name, String temp, String time, String dilution) {
		super();
		this.name = name;
		this.temp = temp;
		this.time = time;
		this.dilution = dilution;
	}

	public String getName() {
		return name;
	}

	public String getTemp() {
		return temp;
	}

	public String getTime() {
		return time;
	}

	public String getDilution() {
		return dilution;
	}

	public long getConter() {
		return conter;
	}

	public void setConter(long conter) {
		this.conter = conter;
	}
}
```


```
import java.io.Serializable;


public class Container implements Serializable 
{
	private String name;
	private String temp;
	private String time;
	private String dilution;
	private String info;	
	
	public Container() {
		super();
	}
	
	public Container(String name, String temp, String time, String dilution, String info) {
		super();
		this.name = name;
		this.temp = temp;
		this.time = time;
		this.dilution = dilution;
		this.info = info;
	}
		
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTemp() {
		return temp;
	}
	public void setTemp(String temp) {
		this.temp = temp;
	}
	public String getTime() {
		return time;
	}
	public void setTime(String time) {
		this.time = time;
	}
	public String getDilution() {
		return dilution;
	}
	public void setDilution(String delution) {
		this.dilution = delution;
	}
	public String getInfo() {
		return info;
	}
	public void setInfo(String info) {
		this.info = info;
	}	
}
```


```
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JComboBox;



public class Names extends JComboBox implements ActionListener
{
	private CBAction cbaction =new CBAction();
	
	
	public Names(Vector<?> items) {
		super(items);
		this.setEditable(true);
		this.addActionListener(cbaction);
	}
	
	public class CBAction implements ActionListener
	{
		boolean found;
		int v;
		int selectedrow = -1;
		int lastselectedrow = -1;
		String selecteditem = "";
		String lastselecteditem = "";
		public void actionPerformed(ActionEvent e) 
		{
			found = false;
			v=0;
//			war ein versuch nur etwas zu machen wenn wirklich was geändet wurde und nicht nur selectiert
//			selectedrow = MainFrame.table.getSelectedRow();
//			selecteditem = getSelectedItem().toString();
//			if(selectedrow == lastselectedrow)// wird ausgeführt wenn es nicht die gleiche reihe wie zuvor und nicht den gleichen namen trägt
//			{
//				System.out.println(selectedrow);
//				System.out.println(lastselectedrow);
//				if(selecteditem.compareTo(lastselecteditem) != 0)
//				{
					if(MainFrame.table.getSelectedRow()>=0)
					{
						System.out.println(MainFrame.table.getEditingRow());
						
						// das weitere ist in dem fall unwichtig aber beschreibt wiso ich die reihe benötige
						
						MainFrame.container.elementAt(MainFrame.table.getSelectedRow()).setName(getSelectedItem().toString());
						while(!found)// sucht die meistgewählten zusatzinfos
						{
							if(v<MainFrame.combos.size())
							{
								if(getSelectedItem().toString().compareTo(MainFrame.combos.elementAt(v).getName()) == 0)
								{
									MainFrame.container.elementAt(MainFrame.table.getSelectedRow()).setTemp(MainFrame.combos.elementAt(v).getTemp());
									MainFrame.container.elementAt(MainFrame.table.getSelectedRow()).setTime(MainFrame.combos.elementAt(v).getTime());
									MainFrame.container.elementAt(MainFrame.table.getSelectedRow()).setDilution(MainFrame.combos.elementAt(v).getDilution());
									found=true;
								}
								else
								{
									v++;
								}
							}
							else
							{
								found = true;
							}							
						}
					}
//				}
//			}
//				
//			lastselectedrow = selectedrow;
//			lastselecteditem = selecteditem;
		}
	}
}
```


----------



## Michael... (22. Jul 2009)

getSelectedRow ist in dem Fall wohl nicht das richtige, was Du brauchst ist:
JTable.html.getEditingRow()


----------



## Gast2 (22. Jul 2009)

Du sollst auch nicht alles schicken sondern es kürzen so dass der effekt einfach nachvollziehbar ist...


----------



## weljo (22. Jul 2009)

Hab bereits den großteil an code entfernt jedoch heist es ja kompilierbar ... hätt noch bei names das popup entfernen können

aber das wirklich wichtige ist eigentlich nur names und MainFrame die beiden anderen sind nur 2 container

ps: um den effekt zu sehn einfach ein bischen mit der ersten spalte spielen und auf die die console achten

getEditingRow klingt zwar gut funktioniert jedoch auch nicht (bekomm nur -1 als würde nicht editiert werden, hab dem DefaultCellEditor(JComboBox) verwendet)


----------



## Ebenius (22. Jul 2009)

Michael... hat gesagt.:


> getSelectedRow ist in dem Fall wohl nicht das richtige, was Du brauchst ist [...]


==>


weljo hat gesagt.:


> also rufe es im action listener auf will in meinem container der die Daten beinhaltet etwas ändern und damit ich weis welcher index es ist brauch ich die zeile


An beide: Nein. Es geht hier um Änderungen am Modell. Also ActionListener wegwerfen und dem Tabellenmodell zuhören. Ein CellEditor verändert das Modell nicht (auch nicht über Listener nach außen). Das tut die JTable über [c]TableModel.setValueAt(...)[/c]. Das Modell selbst gibt Bescheid, wann es sich geändert hat; dem kann man dann zuhören.

Ebenius


----------



## weljo (23. Jul 2009)

thx ... man müsste ja nur alle listener kennen.


----------



## Ebenius (23. Jul 2009)

TableModelListener ans Modell hängen; das hast Du sicher schon rausgefunden. Wenn das Thema erledigt ist, kannst Du bitte den Knopf neben "Antworten" (gibt's über und unter der Beitragsliste) drücken, um das Thema als "[Erledigt]" zu markieren.

Übrigens immer eine brauchbare Referenz: Sun Java™ Tutorial: How to Use Tables. Das ganze Tutorial ist nicht schlecht. 

[EDIT] Den Knopf hast Du offenbar schon gefunden. 

Ebenius


----------

