AWT/Swing: Problem mit Anordnung Elemente, Dateiauswahl und Buttonauswahl

Hallo, erst der Programmcode, dann das Probleme.

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg08renamer;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Enumeration;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.filechooser.FileFilter;

/**
 * @author CB
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        final JFrame jf = new JFrame("Renamer");
        jf.setLayout(new GridLayout(1, 2));
        JPanel jp1 = new JPanel(new GridLayout(6, 1));
        JPanel jp2 = new JPanel(new GridLayout(1, 1));
        final JFileChooser jfc = new JFileChooser();
        jfc.setMultiSelectionEnabled(false);
        jfc.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.isDirectory() && f.canWrite() && f.getParent() != null;
            }

            @Override
            public String getDescription() {
                return "Verzeichnis.";
            }
        });
        JButton auswahl = new JButton("Verzeichnis wählen...");
        final ButtonGroup bg = new ButtonGroup();
        final JRadioButton jrb1 = new JRadioButton("timt");
        final JRadioButton jrb2 = new JRadioButton("");
        final JRadioButton jrb3 = new JRadioButton("");
        final JRadioButton jrb4 = new JRadioButton("jrb4");
        JButton start = new JButton("Start");
        JTextArea jta = new JTextArea("Ausgabe
");
        JScrollPane jsp = new JScrollPane(jta);

        jf.add(jp1);
        jf.add(jp2);
        jp1.add(auswahl);
        bg.add(jrb1);
        bg.add(jrb2);
        bg.add(jrb3);
        bg.add(jrb4);
        jp1.add(jrb1);
        jp1.add(jrb2);
        jp1.add(jrb3);
        jp1.add(jrb4);
        jp1.add(start);
        jp2.add(jsp);

        auswahl.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jfc.showOpenDialog(jf);
            }
        });
        start.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                File folder = jfc.getSelectedFile();
                JRadioButton jrb = null;
                Enumeration<AbstractButton> eab = bg.getElements();
                for (AbstractButton ab = eab.nextElement(); eab.hasMoreElements(); ab = eab.nextElement()) {
                    if (ab.isSelected()) {
                        jrb = (JRadioButton) ab;
                        break;
                    }
                }
                if (folder == null || jrb == null) {
                    return;
                }
                if (false) {
                } else if (jrb == jrb1) {
                    System.out.println("jrb1");
                } else if (jrb == jrb2) {
                    System.out.println("jrb2");
                } else if (jrb == jrb3) {
                    System.out.println("jrb3");
                } else if (jrb == jrb4) {
                    System.out.println("jrb4");
                }
            }
        });

        jf.pack();
        jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        jf.setVisible(true);
    }
}```



Jetzt die Probleme:
1) in welcher Anordnung Elemente listet man alle Komponenten (Panel, Button usw.) auf?
2) ich kann über den JFC kein Verzeichnis auswählen, sondern nur Datei?
3) nachdem ich JRB4 ausgewählt habe, gibt es keine Ausgabe?

Danke im Voraus für alle Hilfe

[quote=CyborgBeta]ich kann über den JFC kein Verzeichnis auswählen, sondern nur Datei?[/quote]Manchmal hilft die API weiter…

bye
TT

Ja danke das rauszusuchen, abgehakt

[quote=CyborgBeta]3) nachdem ich JRB4 ausgewählt habe, gibt es keine Ausgabe?[/quote]Wann wird nochmal die dritte Komponente in der for-Deklaration abgearbeitet?
[HR][/HR]

[quote=CyborgBeta;88598]1) in welcher Anordnung Elemente listet man alle Komponenten (Panel, Button usw.) auf?[/quote]Worauf zielt diese Frage? willst Du einen Desing-Tipp?

bye
TT

Alles klar, dann habe ich jetzt:

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg08renamer;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Enumeration;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.filechooser.FileFilter;

/**
 * @author CB
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        final JFrame jf = new JFrame("Renamer");
        jf.setLayout(new GridLayout(1, 2));
        JPanel jp1 = new JPanel(new GridLayout(6, 1));
        JPanel jp2 = new JPanel(new GridLayout(1, 1));
        final JFileChooser jfc = new JFileChooser();
        jfc.setMultiSelectionEnabled(false);
        jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        jfc.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.isDirectory() && f.canWrite() && f.getParent() != null;
            }

            @Override
            public String getDescription() {
                return "Verzeichnis.";
            }
        });
        JButton auswahl = new JButton("Verzeichnis wählen...");
        final ButtonGroup bg = new ButtonGroup();
        final JRadioButton jrb1 = new JRadioButton("timt...");
        final JRadioButton jrb2 = new JRadioButton("");
        final JRadioButton jrb3 = new JRadioButton("");
        final JRadioButton jrb4 = new JRadioButton("jrb4");
        JButton start = new JButton("Start");
        JTextArea jta = new JTextArea("Ausgabe
");
        JScrollPane jsp = new JScrollPane(jta);

        auswahl.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jfc.showOpenDialog(jf);
            }
        });
        start.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                File folder = jfc.getSelectedFile();
                JRadioButton jrb = null;
                for (Enumeration<AbstractButton> eab = bg.getElements(); eab.hasMoreElements();) {
                    AbstractButton ab = eab.nextElement();
                    if (ab.isSelected()) {
                        jrb = (JRadioButton) ab;
                        break;
                    }
                }
                if (folder == null || jrb == null) {
                    return;
                }
                if (false) {
                } else if (jrb == jrb1) {
                    System.out.println("jrb1");
                } else if (jrb == jrb2) {
                    System.out.println("jrb2");
                } else if (jrb == jrb3) {
                    System.out.println("jrb3");
                } else if (jrb == jrb4) {
                    System.out.println("jrb4");
                }
            }
        });

        jf.add(jp1);
        jf.add(jp2);
        jp1.add(auswahl);
        bg.add(jrb1);
        bg.add(jrb2);
        bg.add(jrb3);
        bg.add(jrb4);
        jp1.add(jrb1);
        jp1.add(jrb2);
        jp1.add(jrb3);
        jp1.add(jrb4);
        jp1.add(start);
        jp2.add(jsp);

        jf.pack();
        jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        jf.setVisible(true);
    }
}```

`bg.getElements(); eab.hasMoreElements();` funktioniert, da Enum..., leider nicht mit der for-each.

Ja, ein Desing-Tipp, man kann die Variablen mit den Komponenten ja in fast jeder Reihenfolge schreiben (im Programmcode). Ich habe mir jetzt gedacht: von außen nach innen oder von oben nach unten und von links nach rechts oder von groß nach klein und JFrame/Panel/usw. ist groß und JButton klein. Gibt es dafür i-welche fest definierten Regeln? GUI-Builder interessieren dabei e-lich nicht.

Edit: `&& f.getParent() != null;` wird anscheinend ignoriert, jedenfalls kann ich auch C:\ auswählen.

[quote=CyborgBeta]funktioniert, da Enum…, leider nicht mit der for-each.[/quote]Als professioneller Programmierer solltest Du Dich exakt ausdrücken: ich sehe in Deinem Code weder ein **enum **noch eine forech-Schleife.
~~
**Dein **Problem ist, das die ButtonGroup keine Implementierung von Iteratable zurückgibt.

**Mein **Problem ist, das Du ButtonGroup.getSelected() nicht verwendest… ;o)
~~
Unsinn, so einfach ist es dann auch nicht.

Anderer seits sind die Radio-Buttons eben Butoons, die eine Action haben sollten…

bye
TT

Enum… == Enumeration

for-each-Schleife funktioniert nur mit Array oder Iterable-Objekt, nicht mit Enumerations

ButtonGroup#getSelected() besteht nicht, ich muss über alle Elemente iterieren und testen, ob genau eins selektiert ist oder keins

Anordnung der Komponenten: nicht auf der GUI, sondern Reihenfolge im Quelltext/Programmcode

for (Enumeration<AbstractButton> eab = bg.getElements(); eab.hasMoreElements();) { begrenzt erst mal den Scope und ist übersichtlich

Ich bin als Progger nur semi-professionell, deshalb frage ich ja auch zwischendurch mal was

Die Sicht in der Auswahlliste des JFileChoosers ist da etwas anders. Hier hat letztendlich jedes File Objekt, das auswählbar ist ein Parent File. Du müsstest Dein Kriterium entsprechend Deiner Bedürfnisse anders wählen, z.B. direkt prüfen ob es sich um C: handelt.

Den Rest habe ich nicht verstanden, daher nur ein allgemeiner Hinweis: Statt über sämtliche Objekt zu iterieren könntest Du den selektierten Button mit Hilfe des ActionCommands o.ä über die ButtonGroup identifizieren. Alternativ ein eigenes Model zum Speichern der aktuellen Selektion.

	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setLayout(new GridLayout(0, 1));
	frame.setBounds(0, 0, 300, 300);
	final ButtonGroup buttongroup = new ButtonGroup();
	for (int i = 0; i < 4; i++) {
		JRadioButton radio = new JRadioButton("Test " + i);
		radio.setActionCommand(radio.getText());
		buttongroup.add(radio);
		frame.add(radio);
	}
	frame.add(new JButton(new AbstractAction("Press") {
		public void actionPerformed(ActionEvent e) {
			if ( buttongroup.getSelection()!=null) {
				String cmd = buttongroup.getSelection().getActionCommand();
				System.out.println(cmd + " selected");
			}
			else
				System.out.println("nothing selected");
		}
	}));
	frame.setVisible(true);```

Das ist seltsam, weil geschrieben wurde, dass auch null zurückgegeben werden kann. Außerdem wird anscheinend auch nur mit Zeichenketten hantiert und es wird keine baumartige Elementestruktur in File aufgebaut:

     * Returns the pathname string of this abstract pathname's parent, or
     * <code>null</code> if this pathname does not name a parent directory.
     * [...]
     */
    public String getParent() {
	int index = path.lastIndexOf(separatorChar);
	if (index < prefixLength) {
	    if ((prefixLength > 0) && (path.length() > prefixLength))
		return path.substring(0, prefixLength);
	    return null;
	}
	return path.substring(0, index);
    }```

Gut, dann nehme ich f.getParent() != null an der Stelle raus, und alles oberflächenmäßige wäre erst mal fertig, so dass ich nun die Programmlogik implementieren/schreiben kann.

Das Programm soll allen Dateien in einem Ordner übrigens so einen Namen geben wie: na595_.jpg usw. nach Änderungsdatum usw., denn Ordnung ist ja das halbe Leben, sagte mal wer.

Edit: Das Andere: Schreibe ich z. B.:

        final JRadioButton jrb1 = new JRadioButton("timt");
        final JRadioButton jrb2 = new JRadioButton("");
        final JRadioButton jrb3 = new JRadioButton("");
        final JRadioButton jrb4 = new JRadioButton("jrb4");```
oder ist
```        final JRadioButton jrb1 = new JRadioButton("timt");
        final JRadioButton jrb2 = new JRadioButton("");
        final JRadioButton jrb3 = new JRadioButton("");
        final JRadioButton jrb4 = new JRadioButton("jrb4");
        final ButtonGroup bg = new ButtonGroup();```
besser? (Die Reihenfolge der Variablen, welche die Komponenten beinhalten, im Quelltext.)

[QUOTE=CyborgBeta]Das Andere: Schreibe ich z. B.:

        final JRadioButton jrb1 = new JRadioButton("timt");
        final JRadioButton jrb2 = new JRadioButton("");
        final JRadioButton jrb3 = new JRadioButton("");
        final JRadioButton jrb4 = new JRadioButton("jrb4");```
oder ist
```        final JRadioButton jrb1 = new JRadioButton("timt");
        final JRadioButton jrb2 = new JRadioButton("");
        final JRadioButton jrb3 = new JRadioButton("");
        final JRadioButton jrb4 = new JRadioButton("jrb4");
        final ButtonGroup bg = new ButtonGroup();```
besser? (Die Reihenfolge der Variablen, welche die Komponenten beinhalten, im Quelltext.)[/QUOTE]

Die Reihenfolge dabei ist doch eigentlich egal. Je nachdem, was du übersichtlicher findest. Ich würde zu Variante 2 tendieren. Du musst halt nur noch die RadioButtons der ButtonGroup hinzufügen. Und das musst du halt machen, nachdem du diese Komponenten erstellt hast.

Also in der Reihenfolge des Aufrufs: jp1, jf, jp2, auswahl, jrb1, bg, jrb2, jrb3, jrb4, start, (jta,) jsp

Aber wäre nicht besser: jf, jp1, jp2, auswahl, bg, jrb1, jrb2, jrb3, jrb4, start, jsp (, jta)

  1. zuerst Container und dann Containerelement
  2. zuerst links und dann rechts
  3. zuerst oben und dann unten

JTA muss ich aber zuerst erstellen, damit JSP sie über den Konstruktor direkt aufnehmen kann, das verletzt die Regel

Kann die IDE die Variablen nicht automatisch nach lesender Stelle sortieren (NetBeans)?

Und was ist mit final-Variablen Methoden anonymer innerer Klassen (Listener-Variablen)?

Danke noch mal für jede Hilfe (auch TT und Michi), bis heute Abend wird erst mal nicht weitergemacht

[quote=CyborgBeta]ie Reihenfolge der Variablen, welche die Komponenten beinhalten, im Quelltext.[/quote]Ich stimme mit Michael überein, dass die Reihenfolge bei der Deklaration absolut egal ist, aber die Namen sollten aussagekräftiger werden.

bye
TT

Ja, ich achte halt auf solche Kleinigkeiten, die sind mir nicht egal.

Wer sich selber “TT” nennt, sollte sich über jta1 (JTextArea1, also das Haupt-Textfeld) als Bezeichung/Namen nicht beschweren, imo.

[quote=CyborgBeta]Ja, ich achte halt auf solche Kleinigkeiten, die sind mir nicht egal.[/quote]Sorry, Du hast uns nach unserer meinung gefragt, dann beschwere Dich nicht, wenn Du eine Antwort bekommst.

Natürlich kannst Du frei äußern, dass Du das anders siehst. Aber so eine persönliche Reaktion halte ich für absolut unangemessen.

Und ja: auch wenn ich ich zu faul bin, meinen Nick voll auszuschreiben habe ich das Recht darauf hinzuweisen, dass ausagekräftige Bezeichner wichtiger sind alls alle anderen Code-Conventionen.

bye
TT