Swingkomponenten modifizieren?

flashray

Erfahrenes Mitglied
Hallo Freunde,

ich habe für meinen Editor den JFileChooser etwas modifiziert, erweitert und folgendes festgestellt.

Der FileChooser hat abhängig welcher Look and Feel (hier: JavaL&F und WinL&F) benutzt wird einen etwas anderen Aufbau.

Ich hatte dem FileChooser ein Paar weitere Elemente wie Label, Combobox, Checkbox etc. hinzugefügt. Zunächst habe ich mir folgendermaßen:

JComponent panelsettings = (JComponent)((JComponent)((JComponent)getComponent(3)).getComponent(2));

das untere Panel mit den zwei Labels, dem Textfeld und der Combobox geholt. Diesen habe ich mit den oben erwähnten Komponenten ergänzt und wieder das Panel dem FileChooser hinzugefügt. Allerdings hat die Implementierung mit dem WinL&F nicht funktioniert.

Da diese Zeile dem Aufbau beim JavaL&F entspricht.
JComponent panelsettings = (JComponent)((JComponent)((JComponent)getComponent(3)).getComponent(2));

Meine Frage ist es, wie würdet ihr eine Swingkomponente erweitern bzw. ergänzen, so dass sich keine oder wenige Kompatibilitätsprobleme zwischen unterschiedlichen Look and Feels entstehen. Auch macht mir diesbezüglich die verschiedenen Javaversionen Sorgen. Sagen wir ich habe das obige Problem durch einen Workaround gelöst, was ist wenn im kommenden Mustang der JFileChooser wieder einen etwas anderen Aufbau hat?

Einen Screenshot meines erweiterten FileChoosers habe ich auch angehängt.

Welche Erfahrungen habt ihr diesbezüglich.

Vg Erdal
 

Anhänge

  • fc.jpg
    fc.jpg
    88,7 KB · Aufrufe: 343
Zuletzt bearbeitet:
Umgehen könntest Du das, wenn Du vom JFileChooser ableitest und z.B. nun einen Label ect. hinzufügst.

Besser wäre es allerdings, den JFileChooser in einem eigenen JPanel (z.B. BorderLayout.CENTER) einzubetten und Deine Erweiterungen in den äußeren Bereichen hinzuzufügen, damit wärest Du unabhängig von unterschiedlichen Aufbauten des JFileChoosers.

P.S.: Mit hardcodierten "Platznummern" die Komponenten zu suchen ist eh ein eher fraglicher Weg. Besser wäre es da, mit "instanceof" und "getText().equals(...)" die richtige JLabel-Komponente zu finden.
 
Hallo Steffen,

Umgehen könntest Du das, wenn Du vom JFileChooser ableitest und z.B. nun einen Label ect. hinzufügst.

Das verstehe ich nicht so ganz. Ob ich ableite oder nicht macht ja keinen Unterschied, da ich ja in dem Sinne nichts überschreibe sondern ergänze.

Besser wäre es allerdings, den JFileChooser in einem eigenen JPanel (z.B. BorderLayout.CENTER) einzubetten und Deine Erweiterungen in den äußeren Bereichen hinzuzufügen, damit wärest Du unabhängig von unterschiedlichen Aufbauten des JFileChoosers.

Ja, stimmt, das wäre eine echte alternative. Allerdings würde hier dann, das Layout etwas leiden. Eher angebappt als integriert würden dann die zusätzlichen Komponenten aussehen. Natürlich wiegt hier auch die korrekte Funktion des Filechooser mehr als das Aussehen.

P.S.: Mit hardcodierten "Platznummern" die Komponenten zu suchen ist eh ein eher fraglicher Weg. Besser wäre es da, mit "instanceof" und "getText().equals(...)" die richtige JLabel-Komponente zu finden.

Kannst du das mal genauer erklären?

Also ich habe mir eine Klasse GetComponents geschrieben.

Code:
import java.awt.Component;

import javax.swing.JComponent;
import javax.swing.JFileChooser;

public class GetComponents {

	public static void getContents(Component[] coms, String s) {
		try {
			for (int i = 0; i < coms.length; i++) {
				System.out.println(s + "." +i + " : " + coms[i].getClass());
			}
			System.out.println();
			for (int i = 0; i < coms.length; i++) {
				getContents(((JComponent) coms[i]).getComponents(), s + "." +i);
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	public static void main(String[] args) {
		JFileChooser fc = new JFileChooser();
		getContents(fc.getComponents(), "J");
	}

}

Ausgabe sieht folgendermaßen aus:
Code:
J.0 : class javax.swing.JPanel
J.1 : class javax.swing.JPanel
J.2 : class sun.swing.FilePane
J.3 : class javax.swing.JPanel

J.0.0 : class javax.swing.JPanel
J.0.1 : class javax.swing.JLabel
J.0.2 : class javax.swing.plaf.metal.MetalFileChooserUI$1

J.0.0.0 : class javax.swing.JButton
J.0.0.1 : class javax.swing.Box$Filler
J.0.0.2 : class javax.swing.JButton
J.0.0.3 : class javax.swing.Box$Filler
J.0.0.4 : class javax.swing.JButton
J.0.0.5 : class javax.swing.Box$Filler
J.0.0.6 : class javax.swing.JToggleButton
J.0.0.7 : class javax.swing.JToggleButton

J.0.2.0 : class javax.swing.plaf.metal.MetalComboBoxButton
J.0.2.1 : class javax.swing.CellRendererPane

javax.swing.CellRendererPane

J.2.0 : class javax.swing.JPanel

J.2.0.0 : class javax.swing.JScrollPane

J.2.0.0.0 : class javax.swing.JViewport
J.2.0.0.1 : class javax.swing.JScrollPane$ScrollBar
J.2.0.0.2 : class javax.swing.JScrollPane$ScrollBar

J.2.0.0.0.0 : class sun.swing.FilePane$3

J.2.0.0.0.0.0 : class javax.swing.CellRendererPane

javax.swing.CellRendererPane
J.2.0.0.1.0 : class javax.swing.plaf.metal.MetalScrollButton
J.2.0.0.1.1 : class javax.swing.plaf.metal.MetalScrollButton

J.2.0.0.2.0 : class javax.swing.plaf.metal.MetalScrollButton
J.2.0.0.2.1 : class javax.swing.plaf.metal.MetalScrollButton

J.3.0 : class javax.swing.JPanel
J.3.1 : class javax.swing.Box$Filler
J.3.2 : class javax.swing.JPanel
J.3.3 : class javax.swing.JPanel

J.3.0.0 : class javax.swing.plaf.metal.MetalFileChooserUI$AlignedLabel
J.3.0.1 : class javax.swing.plaf.metal.MetalFileChooserUI$3

J.3.2.0 : class javax.swing.plaf.metal.MetalFileChooserUI$AlignedLabel
J.3.2.1 : class javax.swing.JComboBox

J.3.2.1.0 : class javax.swing.plaf.metal.MetalComboBoxButton
J.3.2.1.1 : class javax.swing.CellRendererPane

javax.swing.CellRendererPane
J.3.3.0 : class javax.swing.JButton
J.3.3.1 : class javax.swing.JButton

Da ich ja nun die Nummern hatte habe ich folgendermaßen den Filechooser erstellt:
Code:
import java.awt.*:
import java.awt.event.*;
import javax.swing.*;

public class D_FileChooser extends JFileChooser {
	JDialog dialog;
	
	JPanel labelpanel = new JPanel();
	
	JPanel combopanel = new JPanel();

	JPanel panel_filetype = new JPanel();

	JCheckBox checkbox = new JCheckBox("   Automatische Dateinamenserweiterung");

	JButton ibutton = new JButton(new ImageIcon("\\info.gif"));

	JLabel label_enc = new JLabel("Kodierung:");

	JComboBox combo2 = new JComboBox(new String[] { "ANSI", "Unicode",
			"Unicode Big Endian", "UTF-8" });

	MouseListener info;

	public D_FileChooser() {
		
		// Modificate //
		
		ibutton.setBorder(BorderFactory.createRaisedBevelBorder());
		ibutton.setContentAreaFilled(false);
		ibutton.setBorderPainted(false);
		ibutton.setFocusPainted(false);
		
		FlowLayout fl = new FlowLayout();
		fl.setAlignment(FlowLayout.TRAILING);
		panel_filetype.setLayout(fl);
		panel_filetype.add(checkbox);
		panel_filetype.add(ibutton);
		
		JComponent label = (JComponent)((JComponent)((JComponent)((JComponent)getComponent(3)).getComponent(2)).getComponent(0));
		JComponent combo1 = (JComponent)((JComponent)((JComponent)((JComponent)getComponent(3)).getComponent(2)).getComponent(1));
		JComponent panelsettings = (JComponent)((JComponent)((JComponent)getComponent(3)).getComponent(2));
		
		GridLayout gl = new GridLayout(3,1);
		gl.setVgap(6);
		labelpanel.setLayout(gl);
		labelpanel.add(label);
		labelpanel.add(new JLabel("Encoding:"));
		labelpanel.add(new JLabel());
		combopanel.setLayout(gl);
		combopanel.add(combo1);
		combopanel.add(combo2);
		combopanel.add(panel_filetype);
		
		panelsettings.setLayout(new BorderLayout());
		panelsettings.add(labelpanel,BorderLayout.WEST);
		panelsettings.add(combopanel,BorderLayout.CENTER);		

	}
	
	protected JDialog createDialog(Component parent) throws HeadlessException {
		dialog = super.createDialog(parent);
		dialog.setSize(800, 500);
		dialog.setResizable(false);
		return dialog;
	}
	
	public static void main (String[] args){
		D_FileChooser fc = new D_FileChooser();
		fc.createDialog(null);
		fc.showOpenDialog(null);
	}
}

Wie meinst du das mit:

"instanceof" und "getText().equals(...)"


Vg Erdal
 
Zuletzt bearbeitet:
Hallo :)

Ich habe folgendes Problem, im FileChooser-Fenster geht mit dem Rechtsklick der Maus ein kleines Popup-Menu auf, diese würde ich gerne bearbeiten/ersetzen.
Leider konnte ich es bisher nicht finden. Ich bin schon durch einige JComponenten gegangen und habe geschaut wo MouseListener liegen und habe vesucht den richtigen zufinden, aber leider ohne Erfolg.
Es wäre sehr freundlich, wenn mir jemand sagen könnte wo sich das Popup-Menu befindet und wie/wo es ausgelöst wird.

Danke. Gruß Felix
 
Zurück