Swing MVC Pattern verstanden, aber Probleme bei der Umsetzung

mavinatic

Bekanntes Mitglied
Hallo,
ich bin gerade einen kleinen TaskManager für mich am schreiben, aber das Problem ist, dass wenn ich Tasks aus einer Datei lade, dann mache ich ein updateData() auf mein JPanel, wo alles gezeichnet ist und repaint() + revalidate() es aber die Daten werden nicht angezeigt 🙁

Hier mein Quelltext:

Java:
package org.gk.todo.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

public class MainPanel extends JPanel {
	private JPanel contentPanel = null;
	private JPanel menuPanel = null;
	private JPanel categoryPanel = null;
	private JPanel tablePanel = null;
	
	private JSplitPane splitPane = null;
	private JTable table = null;
	private JTree tree = null;
	private String[] menuButtons = new String[] { "Task anzeigen" ,"Neuer Task", "Task bearbeiten", "Task löschen", "Liste laden", "Liste speichern", "Info"};
	private JButton[] button = new JButton[menuButtons.length];
	private String[] columns = new String[] { "Name", "Priority", "Status"};
	private String[][] data = new String[][] {};
	private DefaultTableModel model = null;
	private ButtonListener listener = null;
	private static final long serialVersionUID = 7239511497188922129L;
	public DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Kategorien");
	
	public MainPanel() {
		this.init();
		this.createMenu();
		this.createContent();
	}
	
	private void init() {
		this.setLayout(new BorderLayout());
		this.listener = new ButtonListener(this);
	}
	
	private void createMenu() {
		this.menuPanel = new JPanel();
		this.menuPanel.setPreferredSize(new Dimension(800,75));
		
		this.menuPanel.setLayout(new GridLayout(1, button.length));
		
		for(int i=0;i<button.length;i++) {
			this.button[i] = new JButton(menuButtons[i]);
			this.button[i].setToolTipText(menuButtons[i]);
			this.button[i].addActionListener(listener);
			this.menuPanel.add(button[i]);
		}
		
		this.add(BorderLayout.NORTH,this.menuPanel);
	}
	
	private void createContent() {
		this.contentPanel = new JPanel();
		this.contentPanel.setLayout(new GridLayout(1,1));
		
		this.categoryPanel = new JPanel();
		this.tablePanel = new JPanel();
		
		this.model = new DefaultTableModel(this.data,this.columns);
		this.tablePanel.setLayout(new GridLayout(1,1));
		this.table = new JTable(this.model);
		this.tablePanel.add(new JScrollPane(this.table));
		
		this.categoryPanel.setLayout(new GridLayout(1,1));
		this.categoryPanel.setPreferredSize(new Dimension(200,200));
		this.tree = new JTree(rootNode);
		this.tree.addTreeSelectionListener(listener);
		this.tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		this.categoryPanel.add(new JScrollPane(this.tree));
		
		this.splitPane = new JSplitPane();
		this.splitPane.setLeftComponent(categoryPanel);
		this.splitPane.setRightComponent(tablePanel);
		
		this.contentPanel.add(this.splitPane);
		this.add(BorderLayout.CENTER,this.contentPanel);
	}
	
	public void updateData(String[][] data) {
		this.data=data;
		this.repaint();
		this.revalidate();
	}
}
Hier mein Actionlistener
Java:
package org.gk.todo.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.gk.todo.beans.Task;
import org.gk.todo.model.TaskManager;

public class ButtonListener implements ActionListener, TreeSelectionListener {
	private MainPanel panel = null;
	private TaskManager manager = new TaskManager();
	private JFileChooser fc = new JFileChooser();
	private DefaultMutableTreeNode root = null;
	private ArrayList<Task> taskList = null;
	private ArrayList<Task> tempList = null;
	
	public ButtonListener(MainPanel panel) {
		this.panel = panel;
		this.root = this.panel.rootNode;
	}
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		if(arg0.getActionCommand().equals("Task anzeigen")) {
			TaskWindow newTask = new TaskWindow("Task anzeigen...");
		}
		if(arg0.getActionCommand().equals("Neuer Task")) {
			TaskWindow newTask = new TaskWindow("Neuer Task anlegen...");
		}
		if(arg0.getActionCommand().equals("Task bearbeiten")) {
			TaskWindow newTask = new TaskWindow("Task bearbeiten...");
		}
		if(arg0.getActionCommand().equals("Task löschen")) {
			
		}
		if(arg0.getActionCommand().equals("Liste laden")) {
			try {
				fc.showOpenDialog(panel);
				File f = fc.getSelectedFile();
				if(f!=null) {
					this.taskList = manager.loadData(f.getAbsolutePath());
					
					String[] strings = manager.getCategorys(this.taskList);	
					for(int i =0;i<strings.length;i++) {
						this.root.add(new DefaultMutableTreeNode(strings[i]));
					}
					
					panel.updateData(this.convert(this.taskList));
				}				
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
		if(arg0.getActionCommand().equals("Liste speichern")) {
			try {
				fc.showSaveDialog(panel);
				File f = fc.getSelectedFile();
				if(f!=null) {
					this.manager.saveData(this.taskList, f.getAbsolutePath());
					JOptionPane.showMessageDialog(panel, "Ihre Liste wurde erfolgreich gespeichert","Liste gespeichert!", JOptionPane.OK_OPTION);
				}				
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
		if(arg0.getActionCommand().equals("Info")) {
			JOptionPane.showMessageDialog(panel, "toDoManager V01.00");
		}
	}
	
	private String[][] convert(ArrayList<Task> taskList) {
		String[][] array = new String[taskList.size()][];
		for(int i=0;i<taskList.size();i++) {
			Task currentTask = taskList.get(i);
			String[] task = new String[] { currentTask.getName(), currentTask.getPriority(), currentTask.getStatus() };
			array[i] = task;
		}
		return array;
	}

	@Override
	public void valueChanged(TreeSelectionEvent e) {
		// TODO Auto-generated method stub
		if(tempList==null || tempList.size()==0) {
			tempList = new ArrayList<Task>();
		} else {
			tempList.clear();
		}
		
		TreePath treepath = e.getNewLeadSelectionPath();
		TreeNode node = (TreeNode) treepath.getLastPathComponent();
		
		if(node.toString().equals("Kategorien")) {
			if(this.taskList != null)
				panel.updateData(this.convert(this.taskList));
		} else {
			if(taskList!=null) {
				for(int i=0;i<taskList.size();i++) {
					if(taskList.get(i).getCategory().equals(node.toString())) {
						tempList.add(taskList.get(i));
					}
				}
			}			
			panel.updateData(this.convert(tempList));
		}
				
		
	}
}

Wäre cool wenn ihr mir erklären könntet warum in der JTable nichts angezeigt wird?! 🙂

Gruß

George
 
da dein Code leider ohne Änderungen nicht für uns kompilierbar ist...würde ich folgendes probieren:

entweder erst validieren und dann repaint aufrufen...oder, das sollte das Problem eigentlich auf alle Fälle lösen: in deiner updateData(String[][] data) ein neues TabelModel setzen:

[java=90]public void updateData(String[][] data) {
this.data = data;
model = new DefaultTableModel(data, columns);
table.setModel(model );
// this.repaint();// wenn, imho erst validieren und dann repainten
// this.revalidate();
}[/code]
 
Ich denke das Problem besteht darin, dass du in der MainPanel - Klasse weder eine paint(Graphics g) noch eine paintComponent(Graphics g) hast. Daher bewirkt der Aufruf von repaint() in updateData(...) gar nichts. Denn in MainPanel hast du nur Komponenten. Was this.revalidate(); bewirken soll, ist mir selbst auch nicht so ganz klar. Vielleicht können da ja andere weiter helfen 🙂
 
dem würde ich widersprechen...da die Klasse MainPanel von JPanel erbt, besitzt sie sowohl ein paintComponent, als auch eine paint() Methode...ob sie nun überschrieben worden ist, oder nicht 😉
Meine 5 Cent^^
 
Java ist Call By Value
this.model = new DefaultTableModel(this.data,this.columns);
hier erzeugst du ein DefaultTableModel mit data das zb auf Speicherstelle A zeigt.

public void updateData(String[][] data) {
this.data = data;

jetzt zeigt data auf Speicherstelle B, aber das model schaut immer noch bei A nach. Du musst wie jgh geschrieben hat dein model aktualisieren...
 
Hat geklappt:

Java:
public void updateData(String[][] data) {
		this.model = null;
		this.model = new DefaultTableModel(data,this.columns);
		this.table.setModel(model);
		this.repaint();
		this.revalidate();
	}

Danke an alle 🙂
 

Zurück
Oben