Spaltenorientierte Komponente, ähnlich JTabbed gesucht

  • Themenstarter Themenstarter comci
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
C

comci

Gast
Hallo,

nach langem passivem lesen, hätte ich jetzt auch mal wieder eine Frage. Ich bin auf der Suche nach einer passenden Swing Komponente, und zwar etwas in der Art:

(links zugeklappt / rechts aufgeklappt)
klappdinger.jpg


Nicht so aufwendig wie im Photoshop, aber eben so, dass man eine Reihe von Components hinzufügen kann. Wobei jede eine Überschrift erhält und wenn man auf die Überschrift Klickt wird die Component ausgeblendet. Ich hoffe das ist verständlich.

Gefunden habe ich leider nichts passenden, was eventuell daran liegen könnten, dass ich nicht weiß wie so eine Komponente heißen könnte. ???:L

Ich hab mir dann gedacht so schwierig kann das doch nicht sein :idea:, nur leider ist es das wohl schon. Und eigentlich wollte ich keinen eigenen LayoutManager schreiben, das muss doch auch einfacher gehen, oder? :?:

Hier meine (nicht funktionierende) Idee:

Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JToggleButton;
import javax.swing.border.BevelBorder;


public class JFoldingSidebar extends JPanel {

	public JFoldingSidebar() {
		setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
	}

	public JComponent add(JComponent comp, String heading) {

		addImpl(packComponent(comp, heading), null, -1);
		return comp;
	}

	public JComponent add(JComponent comp, String heading, int index) {

		addImpl(packComponent(comp, heading), null, index);
		return comp;
	}

	private JComponent packComponent(JComponent comp, String heading) {

		final JScrollPane scroll = new JScrollPane();
		scroll.setViewportView(comp);

		final JPanel box = new JPanel(new BorderLayout());

		final JToggleButton head = new JToggleButton(heading);
		head.setOpaque(true);
		head.setBackground(Color.LIGHT_GRAY);
		head.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		head.setPreferredSize(new Dimension(head.getPreferredSize().width,26));
		head.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				//scroll.setVisible(!scroll.isVisible());
				if (box.getComponentCount() == 2)
					box.remove(scroll);
				else
					box.add(scroll, BorderLayout.CENTER);
				JFoldingSidebar.this.revalidate();
			}
		});



		box.add(head, BorderLayout.NORTH);
		box.add(scroll, BorderLayout.CENTER);

		return box;
	}


	public static void main(String[] args) {

		JFrame frame = new JFrame();

		JFoldingSidebar folding = new JFoldingSidebar();
		folding.add(new JSlider(), "Filter1");
		folding.add(new JSlider(), "Filter2");
		JPanel larger = new JPanel();
		larger.add(new JLabel("hello world"));
		larger.add(new JLabel("hello world 2"));
		folding.add(larger, "Filter3");

		frame.getContentPane().setLayout(new BorderLayout());
		frame.getContentPane().add(folding, BorderLayout.EAST);

		frame.pack();
		frame.setVisible(true);
	}

}

Bin für jede Hilfe / Anregung dankbar.

Grüße,
Sebastian
 
Hab mal schnell was gebaut:
Code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;


public class JFloatingTabbedPane extends JTabbedPane
{
	
	private int lastIndex = 0;
	private boolean extended = true;
	
	public JFloatingTabbedPane()
	{
		super();
		init();
	}
	
	public JFloatingTabbedPane(int tabPlacement)
	{
		super(tabPlacement);
		init();
	}
	
	public JFloatingTabbedPane(int tabPlacement, int tabLayoutPolicy)
	{
		super(tabPlacement,tabLayoutPolicy);
		init();
	}

	private void init()
	{
		addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent e)
			{
				super.mouseClicked(e);
								
				if(getSelectedIndex() == lastIndex && e.getClickCount() >= 2)
				{
					setExtensionState(!extended);
				}
				lastIndex = getSelectedIndex();
			}
		});
		
		addComponentListener(new ComponentAdapter()
		{
			@Override
			public void componentResized(ComponentEvent e)
			{
				// TODO Auto-generated method stub
				super.componentResized(e);
				setExtensionState(extended);
			}
		});
	}
	
	@Override
	public void add(Component component, Object constraints, int index)
	{
		// TODO Auto-generated method stub
		super.add(component, constraints, index);
		setExtensionState(extended);
	}
	
	private void setExtensionState(boolean extended)
	{
		int rows = getUI().getTabRunCount(this);
		Rectangle tabBounds  = getUI().getTabBounds(this, getSelectedIndex());
		
		Dimension compDimension = new Dimension(0,0);
		
		compDimension = getSelectedComponent().getPreferredSize();

		int width = getWidth();
		int height = tabBounds.height*rows;
			
		if(extended)height += compDimension.height;
		
		setBounds(getX(),getY(),width,height);
		setPreferredSize(new Dimension(width,height));
		this.extended = extended;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		JFrame test = new JFrame();
		JFloatingTabbedPane jtp = new JFloatingTabbedPane();
		
		JPanel p1 = new JPanel();
		p1.setBackground(Color.red);
		p1.setPreferredSize(new Dimension(100,100));
		
		jtp.add("TEST1", new JPanel());
		jtp.add("TEST2", p1);
		jtp.add("Lala", new JButton("TEST"));
		test.add(jtp);
		test.pack();
		test.setVisible(true);
		test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}

}

Ist nicht besonderst sauber, funzt aber fürs erste.
Du musst allerdings jeder Componente eine PreferredSize mitgeben. (Zumindest die Höhe)

EDIT 21:03
 
Danke für den Code, dass ist aber nicht dass, was ich mir vorgestellt habe. Es geht nicht darum einzelne Tabs zu "schließen", sondern ich will beliebige Components untereinander anordnen, wobei sich die gerade sichtbaren Components den verfügbaren Raum teilen.
Um bei dem Bild aus dem Ursprungsposting zu bleiben geht es darum wo die Tabs drin sind, nicht um die Tabs selber. Ich hoffe das ist irgendwie klarer jetzt. :autsch:


Ariol hat gesagt.:
Hab mal schnell was gebaut:
Code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;


public class JFloatingTabbedPane extends JTabbedPane
{
	
	private int lastIndex = 0;
	private boolean extended = true;
	
	public JFloatingTabbedPane()
	{
		super();
		init();
	}
	
	public JFloatingTabbedPane(int tabPlacement)
	{
		super(tabPlacement);
		init();
	}
	
	public JFloatingTabbedPane(int tabPlacement, int tabLayoutPolicy)
	{
		super(tabPlacement,tabLayoutPolicy);
		init();
	}

	private void init()
	{
		addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent e)
			{
				super.mouseClicked(e);
								
				if(getSelectedIndex() == lastIndex && e.getClickCount() >= 2)
				{
					setExtensionState(!extended);
				}
				lastIndex = getSelectedIndex();
			}
		});
		
		addComponentListener(new ComponentAdapter()
		{
			@Override
			public void componentResized(ComponentEvent e)
			{
				// TODO Auto-generated method stub
				super.componentResized(e);
				setExtensionState(extended);
			}
		});
	}
	
	@Override
	public void add(Component component, Object constraints, int index)
	{
		// TODO Auto-generated method stub
		super.add(component, constraints, index);
		setExtensionState(extended);
	}
	
	private void setExtensionState(boolean extended)
	{
		int rows = getUI().getTabRunCount(this);
		Rectangle tabBounds  = getUI().getTabBounds(this, getSelectedIndex());
		
		Dimension compDimension = new Dimension(0,0);
		
		compDimension = getSelectedComponent().getPreferredSize();

		int width = getWidth();
		int height = tabBounds.height*rows;
			
		if(extended)height += compDimension.height;
		
		setBounds(getX(),getY(),width,height);
		setPreferredSize(new Dimension(width,height));
		this.extended = extended;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		JFrame test = new JFrame();
		JFloatingTabbedPane jtp = new JFloatingTabbedPane();
		
		JPanel p1 = new JPanel();
		p1.setBackground(Color.red);
		p1.setPreferredSize(new Dimension(100,100));
		
		jtp.add("TEST1", new JPanel());
		jtp.add("TEST2", p1);
		jtp.add("Lala", new JButton("TEST"));
		test.add(jtp);
		test.pack();
		test.setVisible(true);
		test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}

}

Ist nicht besonderst sauber, funzt aber fürs erste.
Du musst allerdings jeder Componente eine PreferredSize mitgeben. (Zumindest die Höhe)

EDIT 21:03
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben