Mehrere Layoutprobleme

GrafDooku

Mitglied
Hallo zusammen,

bin ganz neu bei java-forum.org, also nicht gleich auf mich los gehen, wenn ich nicht alles gleich richtig formuliere.
Ich habe ein Tool entwickelt welches verschiedene Arten von Belegungen verwalten kann die über einen oder mehrere Tage laufen. Dieses Tool hat zur Darstellung der Zeitleiste ein hoch komplexes Layoutsystem welches mir immer wieder Schwierigkeiten bereitet. Das Tool arbeitet mit einer MySQL-Datenbank.
Es können Objekte (Zimmer, Maschinen, ...) angelegt werden und diesen Belegungen zugewiesen werden. Die Belegung wird dann im Zeitstreifen des jeweiligen Objekts als Streifen dargestellt. Die Länge des Streifens ergibt sich aus der Dauer der Belegung.
Das Layout ist folgendermaßen verschachtelt:
ContentPane (BorderLayout)
ToolBar​
mainSplitPane (vertical split)​
detailPanel (GridBagLayout) --> Details zur ausgewählten Belegung​
contentSplitPane (horizontal split)​
objektPanel (GridBagLayout) --> Liste der angelegten Objekte als Buttons​
belegungenScrollPane​
mainPanel (BorderLayout)​
belegungPanel (GridBagLayout)​
zeitstreifenPanel (BoxLayout) --> Anzeige Tage, Monate, Jahre​
belegungenPanelStreifenl (BoxLayout) --> Für jedes Objekt ein Streifen​
belegungenPanel (nullLayout)​
einzelBelegungPanel --> Belegungsstreifen​

Unwichtigere Layout-Elemente habe ich weg gelassen. 😉
Nun zu Problem nummer eins.
Ich habe die "contentSplitPane" in eine eigene Klasse ausgelagert damit deren Inhalt bei Veränderung der Daten mithilfe einer kleinen reload-Methode aktualisiert werden kann. Nach dem Auslagern ist der Inhalt von "objektPanel" nicht mehr oben links angeordnet sondern mittig. Hat jemand eine Idee warum das so ist?
Hier mal paar Codeschnipsel dazu:
Java:
private JSplitPane getJSplitPane1() {
	if (jSplitPane1 == null) {
		jSplitPane1 = new MainSplitPane(this);
	}
	return jSplitPane1;
}
Java:
private void initialize() {
	this.setLeftComponent(getObjektPanel());
	this.setRightComponent(getObjekteScrollPane());
}
Java:
private JPanel getObjektPanel() {
	if (objektPanel == null) {
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
		objektPanel = new JPanel();
		objektPanel.setLayout(new GridBagLayout());
		objektPanel.setPreferredSize(new Dimension(200, 0));
		JPanel oben = new JPanel();
		oben.setMinimumSize(new Dimension(200, 145));
		oben.setPreferredSize(new Dimension(200, 145));
		objektPanel.add(oben, gridBagConstraints);
		int x = 1;
		for (Objekt o : ol) {
			gridBagConstraints.gridx = 0;
			gridBagConstraints.gridy = x;
			objektPanel.add(getObjektButton(o), gridBagConstraints);
			x++;
		}
		x++;
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = x;
		objektPanel.add(getNeuObjektButton2(), gridBagConstraints);
		int freiraum = x * 30 + 89;
		if (freiraum < this.getHeight()) {
			JPanel unten = new JPanel();
			unten.setMinimumSize(new Dimension(200, this.getHeight() - freiraum));
			unten.setPreferredSize(new Dimension(200, this.getHeight() - freiraum));
			gridBagConstraints.gridx = 0;
			gridBagConstraints.gridy = x+1;
			objektPanel.add(unten, gridBagConstraints);
		}
	}
	return objektPanel;
}

Mein zweites Problem hängt mit dem neu Zeichnen der Belegungen zusammen.
Java:
public MainPanel reload() {
	this.removeAll();
	belegungPanel = null;
	initialize();
	this.updateUI();
	return this;
}

Sobald diese Methode aufgerufen wird springt das Programm wieder an den Anfang der Zeitleiste.
Wie kann ich ihn dazu veranlassen wieder zu dem Punkt zurückzukehren an dem er vor dem reload war?

Drittes Problem ist ähnlich.
Es wird die aktuelle Woche rot markiert angezeigt.
Wie schaffe ich es, dass das Programm beim starten zu dieser spring um die Woche anzuzeigen und nicht den Anfang des Jahres?

Das vierte Problem hängt denke ich auch mit dem reload zusammen.
Wenn ein neues Objekt eingefügt wird verschwindet die Anzeige aller Belegungen. Wenn dann im neuen Objekt eine weitere Belegung erzeugt wird werden auch alle anderen wieder angezeigt. Ideen?

Fünftes und letztes Problem vorerst.
Es ist möglich innerhalb eines Objekts die Belegung mittels Drag and Drop zu verschieben.
Allerding ist es mir noch nicht gelungen dies auch Objektübergreifend zur Verfügung zu stellen.
Dazu gebe ich am besten mal den Code für die Belegungsstreifen an.
Java:
public class Farbstreifen extends JPanel implements ActionListener {
	protected MainWindowController controller;
	BestaetigenBelegungController bbc = new BestaetigenBelegungController();;
	private String name;
	private Point dragged;
	private int currentDay = 0;
	private Belegung belegung = null;
	private Belegungliste bl = null;
	private Ausgabe_Zeitstreifen az = null;
	private int y = 0;
	protected MainWindowFrame mwf;
	private JPopupMenu menu = null;
	private JMenuItem mi = null;
	private JMenu status = null;
	private JRadioButtonMenuItem rbMenuItemU = null;
	private JRadioButtonMenuItem rbMenuItemB = null;
	private JRadioButtonMenuItem rbMenuItemF = null;
	private JRadioButtonMenuItem rbMenuItemA = null;
	private JRadioButtonMenuItem rbMenuItemFe = null;
	
	public Farbstreifen(Belegung b, MainWindowFrame owner, int[] jahre) {
		this.name = b.getBelegungName();
		this.belegung = b;
		this.mwf = owner;
		setBackground(new Color(255, 255, 255, 200));
		setOpaque(true);
		setSize(new Dimension((int)(b.getBelegungDauer()*10), 30));
		setFont(new Font("Arial",Font.BOLD,10));
		if (b.getBelegungStatus() == 0) {
			setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.BLUE));
		}
		else if (b.getBelegungStatus() == 1) {
			setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.ORANGE));
		}
		else if (b.getBelegungStatus() == 2) {
			setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.RED));
		}
		else if (b.getBelegungStatus() == 3) {
			setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.GREEN));
		}
		else {
			setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.BLACK));
		}
		int startPos = 0;
		Calendar cal = new GregorianCalendar();
		cal.set( b.getStartJahr(), Calendar.JANUARY, 1, 0, 0, 0 ); 
		long time = b.getBelegungStartdate().getTime().getTime() - cal.getTime().getTime();  // Differenz in ms
		long days = Math.round( (double)time / (24. * 60.*60.*1000.) );     // Differenz in Tagen
		startPos = (int) days;
		startPos *= 14;
		startPos -= 14;
		startPos += (b.getStartMonat()-1);
		bl = new Belegungliste();
		if (jahre.length > 0 && jahre[0] < b.getStartJahr()) {
			az = new Ausgabe_Zeitstreifen();
			for (int jahr : jahre) {
				if (jahr < b.getStartJahr()) {
					startPos += az.getWith(jahr);
				}
				else {
					break;
				}
			}
		}
		setLocation(startPos, 0);
		addMouseListener(new MouseAdapter() {
			
			@Override
			public void mouseReleased(MouseEvent e) {
				mwf.getController().setDetailLabelText(Farbstreifen.this.belegung);
				if (e.isPopupTrigger()) {
	                showMenu(e);
	            }
				else if (dragged != null) {
					int d = dragged.x - e.getX();
					if (getCursor().equals(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR))) {
						Belegungliste bl = new Belegungliste(belegung.getBelegungObjekt());
						setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
						if ( dragged.x < getWidth()/2) { //links
							
						} else { // rechts
							y = (e.getX() - d)/14*14;
							if (y > 0) {
								setSize(y, getHeight());
								Belegung bNeu = belegung;
								bNeu.setBelegungDauer(bNeu, y/14);
								bl.aendern(belegung, bNeu, belegung.getBelegungObjekt());
								mwf.getController().checkStatus(bNeu);
							}
						}
						y = 0;
					} else if (getCursor().equals(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR))) {
						Belegungliste bl = new Belegungliste(belegung.getBelegungObjekt());
						Belegung bNeu = belegung;
						GregorianCalendar calendar = new GregorianCalendar(belegung.getStartJahr(), 0, 1);
						calendar.add(Calendar.MONTH, 0);
						calendar.add(Calendar.DAY_OF_MONTH, 1);
						if (belegung.getStartMonat() > 4) {
							calendar.add(bNeu.getBelegungStartdate().DAY_OF_YEAR, (getLocation().x/14 - 2));
						}
						else {
							calendar.add(bNeu.getBelegungStartdate().DAY_OF_YEAR, (getLocation().x/14 - 1));
						}
						bNeu.getBelegungStartdate().setTimeInMillis(calendar.getTimeInMillis());
						bl.aendern(belegung, bNeu, belegung.getBelegungObjekt());
						mwf.getController().checkStatus(bNeu);
					}
					dragged = null;
				}
			}
			
			@Override
			public void mousePressed(MouseEvent e) {
				if (belegung.getBelegungStatus() != 4) {
					dragged = e.getPoint();
					currentDay = getLocation().x/14;
				}
			}
			
			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
			}
			
			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
				if (e.getX() > getWidth()-3 && e.getX() <= getWidth()) {
					setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
				}
				else {
					setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
				}
			}
			
			@Override
			public void mouseClicked(MouseEvent arg0) {
				// TODO Auto-generated method stub
				if (getCursor().hashCode() == Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR).hashCode()) {
					setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
				}
			}
		});
		addMouseMotionListener(new MouseMotionListener() {
			
			@Override
			public void mouseMoved(MouseEvent e) {
				if (e.getX() > getWidth()-3 && e.getX() <= getWidth()) {
					setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
				}
				else {
					setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
				}
			}
			
			@Override
			public void mouseDragged(MouseEvent e) {
				if (dragged != null) {
					if (belegung.getBelegungStatus() != 4) {
						int d = dragged.x - e.getX();
						int dy = dragged.y - e.getY();
						if (getCursor().equals(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR))) {
							setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
							if ( dragged.x < getWidth()/2) { //links
								
							} else { // rechts
								y = (e.getX() - d)/14*14;
								if (y > 0) {
									setSize(y, getHeight());
								}
							}
						} else if (getCursor().equals(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) && y == 0) {
		//					intoperation - nachkommerstellen werden abgeschnitten - auf ganze 14 runden
							setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
							int x = (getLocation().x - d)/14*14;
							int c = (currentDay-x/14)*-1;
							setLocation(x, getLocation().y);
						}
						if (y != 0) {
							setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
						}
					}
				}
			}
		});
	}
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		g.setFont(getFont());
		g.setColor(Color.BLACK);
		g.drawString(name, 0,getFont().getSize());
	}
}

Da das ganze Projekt sehr umfangreich ist, weiß ich nicht welchen Code ich alles rein stellen soll um nicht alles mit Code voll zu stopfen und trotzdem genug Infos zu liefern. Deshalb bitte einfach sagen, wenn noch weitere Infos oder Codeschnipsel benötigt werden.
Zur besseren Veranschaulichung habe ich noch einen Screenshot mit angehängt wie das Programm im Moment aussieht.

Vielen Dank schonmal für euere Mühen und Hilfe.
 

Anhänge

  • belegungstool-Screenshot.jpg
    belegungstool-Screenshot.jpg
    61 KB · Aufrufe: 21
Zuletzt bearbeitet:
Und du erwartest jetzt dass sich irgendwer opfert, deinen Code entschlüsselt und dann deine Fehler korrigiert? Sorry. Was du aber machen kannst, ist zu versuchen ein KSKB zu erstellen (mit der Maus über KSKB fahren und Tooltip lesen). Das heisst du versuchst mit so wenig Code wie möglich, deinen Fehler zu reproduzieren.
Meistens kommst du alleine dadurch schon darauf, was du falsch gemacht hast, in jedem Fall kann man dir dann aber auch besser helfen.
 
Hallo bERt0r,

danke für die schnelle und direkte Antwort.
Hätte ich eigenlich auch selbst drauf kommen können.

Habe nun mal Problem Nummer eins mit dem mittig ausgerichteten Layout nach Auslagerung der inneren SplitPane in eine eigene Klasse dahingehend probiert und habe lediglich feststellen können, dass es nicht nur in der linke Seite ist, sondern auch in der rechten.

Aus diesem Grund habe ich mal das lauffähige kleine Projekt in ein zip gepackt und ein Screenhot mit beigefügt.
Die drei Relevanten Dateien befinden sich im Package software.mainWindow.view.

Ich bin wirklich Ratlos warum der Fehler erst auftritt, wenn die SplitPane in eine eigene Klasse ausgelagert wird.
 

Anhänge


Zurück
Oben