Bugs mit dynamischen Panel und JScrollPane

Bratkartoffel

gebratene Kartoffel
Premium-User
Hallo Leute,

stehe gerade vor einem ziemlich fiesen Problem, welches mich schon seit Stunden beschäftigt.
Ich habe einen JFrame mit einem BorderLayout. Im Westen ist eine Art Menüleiste mit aufklappbaren Panels, mit einem JScrollPane da die aufgeklappten Optionen sonst unten rausrutschen würden.

Das ganze sieht wie auf folgendem Screen aus: Klick

Nun zu meinem Problem:
Sobald ich alle Menüpunkte ausklappe und dann runterscrolle, gibt es Grafikfehler, gut zu sehen auf diesem Screenshot.
Wenn ich nun einen Button klicke, dann wird das Panel mit den Menüpunkten ein gutes Stück kleiner, sodass man nun auch nach rechts scrollen kann, zu sehen auf diesem Screenshot.

Nachfolgend mal der Sourcecode von meiner Panels-Klasse:
Java:
package application.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

/**
 * Klasse welches ein Panel mit auf- und zuklappbaren Panels generiert.<br>
 * Diese Unterpanels enthalten dann einen oder mehrere Buttons.<br>
 * <br>
 * <code><pre>
 * ActionListener listener = new ActionListener() {
 *   public void actionPerformed(ActionEvent e) {
 *     System.out.println(e.getActionCommand());
 *   }
 * };
 * 
 * ExpandingPanels menu = new ExpandingPanels();
 * 
 * ActionPanel ap1 = new ActionPanel("step 1");
 * ap1.addButton("b1", listener);
 * ap1.addButton("b2", listener);
 * ap1.addButton("b3", listener);
 * 
 * ActionPanel ap2 = new ActionPanel("step 2");
 * ap2.addButton("x1", listener);
 * ap2.addButton("x2", listener);
 * 
 * menu.add(ap1);
 * menu.add(ap2);
 * </pre></code>
 * 
 * @author *schnipp*
 * @since 2010/06/24
 * @version 1.0
 */
public class ExpandingPanels extends JPanel implements MouseListener {
	private static final long serialVersionUID = -2992227807058957436L;

	public static final Font FONT_CAPTION = new Font("Monospaced", Font.PLAIN, 14);

	public static final Dimension SIZE_CAPTION = new Dimension(150, 30);

	private ArrayList<ActionPanel> panels;

	public ExpandingPanels() {
		super(new FlowLayout(SwingConstants.LEADING));

		panels = new ArrayList<ActionPanel>();
	}

	public Dimension getPreferredSize() {
		Dimension b = new Dimension();
		b.width = SIZE_CAPTION.width + 10;
		
		for (ActionPanel p : panels) {
			b.height += p.getPreferredSize().height + 8;
		}

		return b;
	}

	public void mouseClicked(MouseEvent e) {
		if (e.getButton() != MouseEvent.BUTTON1) return;

		if (e.getSource() instanceof JButton) {
			JButton b = (JButton) e.getSource();

			b.doClick();
		}

		if (e.getSource() instanceof ActionPanel) {
			ActionPanel ap = (ActionPanel) e.getSource();
			
			ap.toggleSelection();
	    revalidate();
	    repaint();
		}
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}

	public void add(ActionPanel ap) {
		ap.addMouseListener(this);

		super.add(ap);
		panels.add(ap);
	}

	public void remove(ActionPanel ap) {
		super.remove(ap);
		panels.remove(ap);
	}

	public int getPanelCount() {
		return panels.size();
	}

	public ActionPanel getPanel(int i) {
		return panels.get(i);
	}

	public static class ActionPanel extends JPanel {
		private static final long serialVersionUID = 5063292173382222443L;

		private JLabel title;
		private JPanel center;

		private boolean selected;

		private ArrayList<JButton> buttons;

		public ActionPanel(String caption) {
			super(new BorderLayout());

			title = new JLabel(caption);
			title.setFont(FONT_CAPTION);
			title.setBackground(Color.DARK_GRAY);
			title.setForeground(Color.LIGHT_GRAY);
			title.setOpaque(true);
			title.setBorder(BorderFactory.createRaisedBevelBorder());
			title.setPreferredSize(SIZE_CAPTION);
			
			center = new JPanel(new GridLayout(0, 1));

			super.add(title, BorderLayout.NORTH);
			super.add(center, BorderLayout.CENTER);

			buttons = new ArrayList<JButton>();
			selected = false;
		}

		public void addButton(String caption, String btn_name,
				ActionListener listener) {
			if (listener == null)
				throw new IllegalArgumentException("ActionListener may not be null!");

			JButton b = new JButton();
			b.setName(btn_name);
			b.setText(caption);
			b.addActionListener(listener);

			buttons.add(b);

			if (selected) center.add(b);
		}

		public void toggleSelection() {
			selected = !selected;

			for (JButton b : buttons) {
				if (selected)
					center.add(b);
				else
					center.remove(b);
			}
		}
	}
}

Ich werd hier langsam wirklich wahnsinnig, warum stolpere immer ich über Java/Swing Bugs :-/

// Edit: Indirekte Lösung: Look&Feel auf Standard lassen, dann sieht man es nicht so deutlich.

Gruß
BK
 
Zuletzt bearbeitet:
Zurück