Swing Architektonisches Problem / Listener / MVC

kaoZ

Top Contributor
Aloha, ein neues Problem tut sich auf :D

Folgende Situation und ich hoffe ich könnt mir nen Tipp geben wie man das ganze möglichst OO Lösen kann

meine GUI setzt sich aus mehreren Bestandteilen ( Komponenten ) zusammen, ich habe einen OO Orientierten Ansatz gewählt und realisiere die einzelnen Komponenten in Separaten Klassen , und dies sorgt grade für mehr Probleme als für Lösungen ,

hier mal ein Beispiel:

Java:
package de.kaoz.components;

import static de.kaoz.constants.Constants.MENUBAR_EDIT;
import static de.kaoz.constants.Constants.MENUBAR_FILE;
import static de.kaoz.constants.Constants.MENUBAR_HELP;
import static de.kaoz.constants.Constants.MENUBAR_OPTION;
import static de.kaoz.constants.Constants.MENUBAR_SEARCH;
import static de.kaoz.constants.Constants.MENUBAR_WINDOW;

import java.util.ArrayList;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class SimpleMenuBar extends JMenuBar{
	private static final long serialVersionUID = 1L;
	
	ArrayList<JMenuItem> itemList = new ArrayList<>();
	
	JMenu fileMenu, editMenu, optionMenu, searchMenu, windowMenu, helpMenu;
	
	public SimpleMenuBar() {
		createMenu();
		addToBar();	
	}

	private void createMenu() {
		fileMenu = new JMenu(MENUBAR_FILE);
			JMenu newFile = new JMenu("Neu...");
			JMenuItem invoice	 = new JMenuItem("Rechnung");
			JMenuItem estimate	 = new JMenuItem("Kostenvoranschlag");
				
				newFile.add(invoice);
				newFile.add(estimate);
				
			JMenuItem openFile	 = new JMenuItem("Öffnen...");
			JMenuItem save		 = new JMenuItem("Speichern");
			JMenuItem saveAs	 = new JMenuItem("Speichern als...");
			JMenuItem print		 = new JMenuItem("Drucken");
			JMenuItem importFile = new JMenuItem("Importieren...");
			JMenuItem exportFile = new JMenuItem("Exportieren...");
			JMenuItem close		 = new JMenuItem("Beenden");
				
			fileMenu.add(newFile);
			fileMenu.add(openFile);
			fileMenu.addSeparator();
			fileMenu.add(save);
			fileMenu.add(saveAs);
			fileMenu.addSeparator();
			fileMenu.add(print);
			fileMenu.addSeparator();
			fileMenu.add(importFile);
			fileMenu.add(exportFile);
			fileMenu.addSeparator();
			fileMenu.add(close);
				
		editMenu = new JMenu(MENUBAR_EDIT);
			JMenuItem stepBack	 = new JMenuItem("Rückgängig machen");
			JMenuItem cut		 = new JMenuItem("Ausschneiden");
			JMenuItem copy		 = new JMenuItem("Kopieren");
			JMenuItem paste		 = new JMenuItem("Einfügen");
			JMenuItem delete	 = new JMenuItem("Löschen");
			
			editMenu.add(stepBack);
			editMenu.addSeparator();
			editMenu.add(cut);
			editMenu.add(copy);
			editMenu.add(paste);
			editMenu.addSeparator();
			editMenu.add(delete);
			
		optionMenu = new JMenu(MENUBAR_OPTION);
			JMenuItem options	 = new JMenuItem("Einstellungen");
			JMenuItem savePath	 = new JMenuItem("Speicherort bearbeiten");
			JMenuItem userData	 = new JMenuItem("Nutzerdaten bearbeiten");
			
			optionMenu.add(options);
			optionMenu.addSeparator();
			optionMenu.add(savePath);
			optionMenu.add(userData);
			
		searchMenu = new JMenu(MENUBAR_SEARCH);
			JMenuItem searchClient	 = new JMenuItem("Kunden suchen");
			JMenuItem searchInvoice	 = new JMenuItem("Rechnung suchen");
			JMenuItem searchEstimate = new JMenuItem("Kostenvoranschlag suchen");
			
			searchMenu.add(searchClient);
			searchMenu.add(searchInvoice);
			searchMenu.add(searchEstimate);
			
		windowMenu = new JMenu(MENUBAR_WINDOW);
			JMenu resolution	 = new JMenu("Auflösung anpassen...");
				JMenuItem small	 = new JMenuItem("800 x 600");
				JMenuItem middle = new JMenuItem("1024 x 768");
				JMenuItem big	 = new JMenuItem("1280 x 1024");
				
				resolution.add(small);
				resolution.add(middle);
				resolution.add(big);
				
			windowMenu.add(resolution);
				
		helpMenu = new JMenu(MENUBAR_HELP);
			JMenuItem shortcuts	 = new JMenuItem("Tastenkombinationen");
			JMenuItem about		 = new JMenuItem("Info");
			JMenuItem support	 = new JMenuItem("Support und Hilfe");
			
			helpMenu.add(shortcuts);
			helpMenu.add(about);
			helpMenu.add(support);
			
	}
	
	private void addToBar(){
		this.add(fileMenu);
		this.add(editMenu);
		this.add(searchMenu);
		this.add(optionMenu);
		this.add(helpMenu);
	}
}

Diese MenuBar binde ich in meiner GUI bzw. dem HauptFrame ein und halte eine Referenz auf darauf

Hier ein ausschnitt:


(Eine Funktionierende Lösung hatte ich bereits geschrieben, allerdings waren da alle Komponenten 'ToolBar / MenuBar' in einer Klasse realisiert, und nicht in eigentständigen. )

Java:
package de.kaoz.views;

import static de.kaoz.constants.Constants.APP_TITLE;
import static de.kaoz.constants.Constants.SCREEN_HEIGHT;
import static de.kaoz.constants.Constants.SCREEN_WIDTH;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.border.EtchedBorder;

import de.kaoz.components.SimpleMenuBar;
import de.kaoz.components.SimpleToolBar;
import de.kaoz.util.FrameFactory;

public class EditorView {
	
	JFrame frame;
	SimpleMenuBar menuBar;  //<<-- Referenz auf die MenuBar
	JToolBar toolBar;
	JPanel contentPane, sidePanel, printPanel, statusBar;
	
	public EditorView() {
		frame = FrameFactory.createFrame(APP_TITLE, SCREEN_WIDTH, SCREEN_HEIGHT, 2, JFrame.MAXIMIZED_BOTH,  null);
		createMenuBar();
		createToolBar();
		createPanel();
		addComponents();
	}
	
	private void createMenuBar(){
		menuBar = new SimpleMenuBar();
	}
	...

Klar , ich könnte jetzt innerhalt der einzelnen Komponenten Innere Klassen erstellen welche das ActionListener Interface implementiert und sich dann um die Eventbehandlung kümmern, allerdings sollte dies ja eigentlich der Controller übernehmen oder nicht (wenn man jetzt von einem MVC Pattern ausgeht) und nicht eine Komponente der View, außerdem müsste ich dann je in jeder Komponente , da diese ja in Separaten Klassen realisiert sind ,
eine Referenz auf das Hauptframe halten und ich dort dementsprechende getter anbieten um an die Panel etc. zu kommen in welche später weitere Komponenten eingefügt werden solle, da ich ja z.B wie im Bild oben beschrieben von der Menu oder Toolbar aus garnicht auf die Panel der eigentlichen GUI zugreifen könnte.

Gibt es da keine sauberere Lösung ?


Bzw. wie wird sowas im Normalfall realisiert, ich könnte natürlich auch den Source Code der MenuBar in der eigentlichen View realisieren , allerdings wäre das doch 1. unschön und 2. nicht sonderlich Objekt Orientiert oder ?

Außerdem bläht das den Source Code doch nur unnötig auf....
 
Zuletzt bearbeitet:

Harry Kane

Top Contributor
Hallo,
normalerweise sollten Teile der Geschäftslogik, die durch Benutzeraktionen ausgelöst werden, in Form von Actions realisiert werden. Diese Actions können, wenn sie denn mal fertig geschrieben sind, direkt zum Aufbau von JMenus und JButtons verwendet werden.
Ich erkenne ehrlich gesagt keine wirklich tieferen Sinn hinter deiner SimpleMenuBar Klasse. Meiner Meinung nach ist es nicht sinnvoll, eine Klasse zu erweitern, nur um in der Kindklasse Methoden der Superklasse aufzurufen.
Wenn Du den Aufbau deines Menüs kapseln möchtest, würde ich dir eine Klasse ActionTree zu definieren, die eine Reihe von Actions in einer baumartigen Struktur vorhält und in der Lage ist, eine übergebene JMenuBar mit den benötigten JMenuItems und JMenus zu befüllen.
...außerdem müsste ich dann je in jeder Komponente , da diese ja in Separaten Klassen realisiert sind ,
eine Referenz auf das Hauptframe halten und ich dort dementsprechende getter anbieten um an die Panel etc. zu kommen in welche später weitere Komponenten eingefügt werden solle,...
Jein. Ich würde absolut NICHT empfehlen, Klassen von JFrame und JPanel abzuleiten, diese mit gettern für verschiedene Komponenten zu versehen, dann die JFrames und JPanels an Listener-Klassen zu übergeben, und dann in der Logik aus den JFrames und JPanels die Komponenten zu beschaffen und damit dann irgendein Zeuch anzustellen.
Andererseits muss natürlich jedes Objekt A, das etwas mit Objekt B anstellt, von diesem wissen. Ein Eventhandler, der den Wert eines JTextFields auslesen soll, und anhand dessen Inhalts irgendwelche Aufgaben anzustoßen, muss eine Referenz auf dieses JTextField bekommen. Dazu reicht es aber aus, dem Eventhandler eine Referenz nur auf das JTextField mitzugeben!
So in etwa:
Java:
public class MVCDemo {
    public static void main(String[] args){
        JFrame frame = new JFrame("MVC Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Box box = new Box(BoxLayout.Y_AXIS);
        JTextField source = new JTextField(20);
        JTextField target = new JTextField(20);
        target.setEditable(false);
        box.add(source);
        box.add(new JButton(new TextChangeAction(source, target)));
        box.add(target);
        frame.setContentPane(box);
        frame.pack();
        frame.setVisible(true);
    }
}
class TextChangeAction extends AbstractAction{
    private JTextComponent source;
    private JTextComponent target;
    
    TextChangeAction(JTextComponent source,JTextComponent target){
        super("Text übernehmen");
        this.source = source;
        this.target = target;
    }
    public void actionPerformed(ActionEvent ae){
        target.setText(source.getText());
    }
}
 

kaoZ

Top Contributor
Hallo,
normalerweise sollten Teile der Geschäftslogik, die durch Benutzeraktionen ausgelöst werden, in Form von Actions realisiert werden

Das habe ich mir währenddessen auch schon angesehen :)

Das realisieren der Toolbar / den Menus in jeweil eigenen Klassen hatte ich angestrebt da ebend der eigentliche Quelltext der GUI wesentlich klarer wird und sich nicht so aufbläht, zudem dachte ich das dieser Ansatz eher Objekt Orientiert wäre da ich ebend Die Toolbar / das Menu wie eigentständige Objekte händel, was diese ja letztendlich auch sind , eben Komponenten aus dennen ich dann das eigentliche GUI zusammensetze, sicher hätte ich das auch einfach in eigenen Methoden realisieren können, nur dachte ich ebend das es in eigenen Klassen saubererer Code wäre :)

Wie gesagt habe ich vorher noch nicht nach dem MVC Pattern gearbeitet, und probiere es grade aus beim Versuch eine art Warenwirtschaftssystem zu erstellen.

Hierzu möchte ich wie in meinem Screenshot bereits angedeutet über die Menubar / Toolbar , anderer Views (JPanel) in der Gui hinzufügen , z.B stellvertretend für eine Rechnung oder eben einen Kostenvoranschlag, wie würde man soetwas realisieren wenn du sagst du würdest diese sachen nicht von in ableitungen von JFrame bzw eher JPanel realisieren ?

Das interessiert mich nun nämlich brennend :)

Mfg
 

kaoZ

Top Contributor
Oder sollte ich den View ( bis auf die Komponenten die nachher meine Rechnung oder ähnliche Dokumente darstellen welche ich als JPanel behandel ) also incl. der Menu und der Toolbar als eine Klasse erstellen, und jeweils das erstellen der einzelnen Bestandteile, toolbar , menus usw. in Methoden Kapseln ?!

Wie gesagt ist mein erstes größeres Projekt und da bin ich ziemlich viel damit beschäftigt über den aufbau des ganzen nachzudenken , anstatt einfach wild drauf los zu programmieren. :)

so spare ich mir hinterher ggf. das ein oder andere Refactoring, wenn ich es gleich vernünftig überdenke und nicht einfach ins blaue schieße.
 

kaoZ

Top Contributor
Nur nochmal zum Verständnis,

ich hab jetzt mal eine Action geschrieben welche mir ein neues "Dokument" (JPanel) in einen bestehenden Container adden soll

Java:
public class InvoiceAction extends AbstractAction{
	private static final long serialVersionUID = 1L;
	
	JComponent target;
	
	public InvoiceAction(JComponent target) {
		super("Neue Rechnung");
		this.target = target;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		target.add(new Invoice());
		target.validate();	
	}

}

und die Action einem JMenuItem hinzugefügt

Java:
	private void createMenuBar(){
		menuBar = new JMenuBar();
		
		JMenu fileMenu = new JMenu(MENUBAR_FILE);
			JMenu newFile = new JMenu("Neu...");
			
			JMenuItem invoice = new JMenuItem(new InvoiceAction(printPanel)); // <<---
			
			newFile.add(invoice);
			fileMenu.add(newFile);
			menuBar.add(fileMenu);
			
		
	}

Hier der Code der nur zum testen in der Klasse Invoice steht:

Java:
public class Invoice extends JPanel{
	private static final long serialVersionUID = 1L;

	public Invoice() {
		setBackground(Color.green);
	}

}

Dies führt allerdings zu einer NPE, und es ist nicht ersichtlich warum oder woher die NPE kommt, selbst wenn ich einen explizieten Cast auf Invoice in meiner Actionklasse durchführe was unnötig ist da diese von JComponent bzw. JPanel abgeleitet wird kommt es zu der Exception. IM Stacktrace lässt sich nicht wirklich rauslesen woher die Exception kommt, ist denn zumindest der Ansatz so wie du es gemeit hast ?!

Selbst wenn ich nicht nur den targetContainer, sondern auch den parent im Konstruktor übergebe schmeißt er mir die NPE.

[EDIT]
Das hier funktioniert dagegen reibungslos :

Java:
	private void createMenuBar(){
		menuBar = new JMenuBar();
		
		JMenu fileMenu = new JMenu(MENUBAR_FILE);
			JMenu newFile = new JMenu("Neu...");
			
			JMenuItem invoice = new JMenuItem("Neue Rechnung");
			invoice.addActionListener(new ActionListener(){

				@Override
				public void actionPerformed(ActionEvent e) {
					printPanel.add(new Invoice());
					printPanel.validate();
				}
			});
			
			newFile.add(invoice);
			fileMenu.add(newFile);
			menuBar.add(fileMenu);
			
		
	}
[/EDIT]

Hier nochmal ein Screen davon :



Ziel ist das ich später einfach ein neues "Dokument" (Rechnung/Kostenvoranschläge) mit definierten TextFeldern usw.... dem printPanel hinzufügen kann um den gesamten Bereich später drucken und eben auch Speichern kann.
 
Zuletzt bearbeitet:

kaoZ

Top Contributor
Nochmal um das Thema aufzugreifen das du die Komponenten nicht ableiten würdest, Invoice stellt eine Rechnung dar, bzw. dem view für diese Rechnung , die Logik hierzu soll dann in einem dementsprechendem model dafür realisiert werden, sprich die Auswahl des Kunden , eventuelle Tabelleninhalte für Arbeitswerte usw. usw.

demnach finde ich schon das es sinn macht den View für eben diese Dokumente als ein Jpanel zu behandeln, da ich mich nicht wie bei Jcomponent darum kümmern muss das die Elemente der View auch gezeichnet werden . Mich würde interessieren wie man so etwas Professionell umsetzen würde!?

auch hier nochmal danke für alle die Helfen und schon mehr Erfahrung damit haben solche Anwendungen zu erstellen:)
 
Zuletzt bearbeitet:

Harry Kane

Top Contributor
Bezüglich der Herkunft der NPE: hast du printPanel initialisiert, bevor du eine Referenz darauf an deine Action übergibst?
Das hier wird NICHT funktionieren:
Java:
JPanel p = null;
Target t = new Target(p);
panel = new JPanel();
t.setPanelColor(Color.green);
class Target{
    private JPanel panel;
    Target(JPanel panel){
        this.panel = panel;
    }
    public void setPanelColor(Color c){
        this.panel.setBackground(c);
    }
}
Um das zu umgehen, musst du deiner InvoiceAction einen gültigen Container übergeben. Dafür braucht es
a) eine setter in der Action-Klasse und
b) eine Referenz auf die Action, so daß die Klasse, die die Menüstruktur erzeugt, darauf zugreifen kann.
Da du offenbar je nach Kontext mehrere Dialoge anzeigen bzw. in dein Hauptfenster einfügen willst, könntest du dir eine Superklasse ViewCreation extends AbstractAction erstellen, die eine Referenz auf einen Container bekommen kann. Davon leitest du die Klasse InvoiceAction, CustomerAction, ReminderAction usw. ab. Diese erzeugen jeweils ein JPanel nach Wunsch und fügen dieses dem Container der Superklasse hinzu. Damit du den ganzen Actions nachträglich noch einen passenden Container verpassen kannst, musst du eine Liste mit Referenzen auf die Actions anlegen.
So, und jetzt noch ein Ansatz zum Thema, wie man datenzentrierte Dialog/Panels machen kann, ohne ständig von JPanel abzuleiten. Ich habe mich mit dieser Thematik mal intensiv auseinandersetzen müssen, und folgender selbst implementierter Ansatz hat gut funktioniert:
Säule 1: Es gibt Objekte mit Eigenschaften. Jede Eigenschaft hat einen Type (String, Number, Boolean, Color, Stroke, Shape). Für jede Eigenschaft eines jeden Objekttyps gibt es eine Klasse, die von der Superklasse Control abgeleietet ist. Jede Control hat eine Referenz auf ein Objekt, dessen Eigenschaften geändert werden, und eine Referenz auf einen Editor, der Eigenschaften eines bestimmten Typs ändern kann. Jeder Editor hat ausserdem eine View, die eine JComponent ist. Jede Änderung am Editor führt dazu, daß die entsprechende Eigenschaft des Objektes gesetzt wird.
Säule 2: Es gibt eine von JPanel abgeleite Klasse, an die eine Liste mit Controls übergeben wird. Aus den View der Controls baut dieses JPanel dann die GUI.
Wen du noch Tabellen usw. brauchst, wird das ganze natürlich komplizierter, aber ich denke noch gut beherrschbar.
Es sieht zwar zunächst nach jeder Menge Tipparbeit aus, für jede Eigenschaft eines jeden Objekttyps eine Control zu programmieren, aber das geht erstens recht schnell von der Hand, und man hat jede Menge Flexibilität, um beispielsweise noich Validierungen etc. zwischenzuschalten.
Java:
public class MVCDemo {
    public static void main(String[] args){
        JFrame frame = new JFrame("MVC Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Box box = new Box(BoxLayout.Y_AXIS);
        JTextField source = new JTextField(20);
        JTextField target = new JTextField(20);
        target.setEditable(false);
        box.add(source);
        box.add(new JButton(new TextChangeAction(source, target)));
        box.add(target);
        ArrayList<Control<?, Kunde>> liste = new ArrayList<Control<?, Kunde>>();
        liste.add(new KundenNachname());
        liste.add(new KundenVorname());
        liste.add(new KundeGut());
        ControlPanel<Kunde> cp = new ControlPanel<Kunde>(liste);
        box.add(cp);
        final Kunde kunde = new Kunde();
        kunde.setVorname("James");
        kunde.setNachname("Bond");
        cp.setItem(kunde);
        JButton anzeigen = new JButton("Print Kunde");
        box.add(anzeigen);
        anzeigen.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                System.out.println("Kunde: " + kunde.toString());
            }
        }
        );
        frame.setContentPane(box);
        frame.pack();
        frame.setVisible(true);
    }
}
class TextChangeAction extends AbstractAction{
    private JTextComponent source;
    private JTextComponent target;
    
    TextChangeAction(JTextComponent source,JTextComponent target){
        super("Text übernehmen");
        this.source = source;
        this.target = target;
        super.putValue(Action.LARGE_ICON_KEY, new ColorIcon(32, 32, Color.RED));
    }
    public void actionPerformed(ActionEvent ae){
        target.setText(source.getText());
    }
}
class ColorIcon implements Icon{
    private int width;
    private int height;
    private Color color;
    ColorIcon(int width, int height, Color color){
        this.width = width;
        this.height = height;
        this.color = color;
    }
    public int getIconHeight(){
        return this.height;
    }
    public int getIconWidth(){
        return this.width;
    }
    public void paintIcon(Component c, Graphics g, int x, int y){
        g.setColor(this.color);
        g.fillRect(x, y, width, height);
    }
}
class Kunde{
    private String vorname;
    private String nachname;
    private boolean good;
    Kunde(){
        this.vorname = "";
        this.nachname = "";
    }
    public void setNachname(String nachname){
        this.nachname = nachname;
    }
    public String getNachname(){
        return this.nachname;
    }
    public void setVorname(String vorname){
        this.vorname = vorname;
    }
    public String getVorname(){
        return this.vorname;
    }
    public boolean isGood(){
        return this.good;
    }
    public void setGood(boolean good){
        this.good = good;
    }
    public String toString(){
        return this.vorname + " "  +this.nachname + ", " + (good ? "guter Kunde" : "kein guter Kunde");
    }
}
abstract class Control<T,I> {

    private I item;

    private ValueEditor<T> editor;

    private String name;

    protected Control(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }

    public void setEditable(I item){
        //System.out.println("[Control.setEditable]");
        JComponent view = editor != null ? editor.getView() : null;
        this.item = item;
        updateEditor();
        if(view != null) view.setEnabled(true);
    }

    public void setNewEditable(I item){
        //System.out.println("[Control.setEditable]");
        JComponent view = editor != null ? editor.getView() : null;
        this.item = item;
        updateItem();
        if(view != null) view.setEnabled(true);
    }

    public I getItem(){
        return item;
    }

    public ValueEditor<T> getEditor() {
        if (editor == null) {
            editor = createEditor();
        }
        return editor;
    }
    public JComponent getView(){
        return getEditor().getView();
    }

    public void actionPerformed(ActionEvent ae) {
        if (ae.getSource() != editor) {
            return;
        }
        updateItem();
    }

    protected abstract ValueEditor<T> createEditor();

    protected abstract void updateItem();

    public abstract void updateEditor();
}
interface ValueEditor<T>{

    public void setObject(T o);

    public T getObject();

    public void addActionListener(ActionListener al);

    public JComponent getView();
    
}
class TextEditor extends JTextField implements ValueEditor<String> {

    public TextEditor() {
        this(7);
    }

    public TextEditor(int columns) {
        super(columns);
    }

    public void setObject(String text) {
        setText(text);
    }

    public String getObject() {
        return getText();
    }
    public JComponent getView(){
        return this;
    }
}
class BooleanEditor extends JCheckBox implements ValueEditor<Boolean>{
    public BooleanEditor(String label){
        super(label);
    }
    public BooleanEditor(){
        super();
    }
    public void setObject(Boolean o){
        if(o instanceof Boolean){
            setSelected( ((Boolean)o).booleanValue());
        }
    }
    public Boolean getObject(){
        return isSelected() ? Boolean.TRUE : Boolean.FALSE;
    }
    public JComponent getView(){
        return this;
    }
}

class KundenNachname extends Control<String, Kunde> implements ActionListener{

    KundenNachname(){
        super("Kundenname");
    }
    protected ValueEditor<String> createEditor(){
        TextEditor e = new TextEditor();
        e.addActionListener(this);
        return e;
    }

    protected void updateItem(){
        getItem().setNachname(getEditor().getObject());
    }

    public void updateEditor(){
        getEditor().setObject(getItem().getNachname());
    }
    
}
class KundenVorname extends Control<String, Kunde> implements ActionListener{

    KundenVorname(){
        super("Kundenvorname");
    }
    protected ValueEditor<String> createEditor(){
        TextEditor e = new TextEditor();
        e.addActionListener(this);
        return e;
    }

    protected void updateItem(){
        getItem().setVorname(getEditor().getObject());
    }

    public void updateEditor(){
        getEditor().setObject(getItem().getVorname());
    }
    
}
class KundeGut extends Control<Boolean, Kunde> implements ActionListener{

    KundeGut(){
        super("Gut ?");
    }
    protected ValueEditor<Boolean> createEditor(){
        BooleanEditor e = new BooleanEditor();
        e.addActionListener(this);
        return e;
    }

    protected void updateItem(){
        getItem().setGood(getEditor().getObject());
    }

    public void updateEditor(){
        getEditor().setObject(getItem().isGood());
    }
}
class ControlPanel<I> extends JPanel{
    private List<Control<?, I>> controls;
    ControlPanel(List<Control<?, I>> controls){
        super.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.controls = controls;
        for(int i = 0; i < controls.size(); i++){
            add(controls.get(i).getView());
        }
    }
    public void setItem(I item){
        for(int i = 0; i < controls.size(); i++){
            controls.get(i).setEditable(item);
        }
    }
}
 

kaoZ

Top Contributor
Ok, ich arbeite mich grad mal durch dein Beispiel, ich finde immer das Innere Klassen das ganze dermaßen unübersichtlich machen das ich es immer lieber in Separaten Klassen packe :)

Also meinst du man solle das ganze mit VO's machen ,ok...

nochmal schnell zu der NPE, selbst wenn ich das JPanel in dem dann das erzeugte angezeigt werden soll vorher durch einen Initialisierungsblock definiere , erhalten ich ich eine NPE ohne wirklich sinnvolle beschreibung des auslösers, ersichtlich ist nur das beim Versuch dem target per .add(); den panel zuzuweisen die NPE ausgelöst wird,

ich arbeite mich nochmal fix in die Actions ein und geb dann Rückmeldung

PS:

wie würdest du die Superklasse für die Actions aufbauen ? Abstrakt ? so dass dann nur die Subklassen die actionPerformed Methode implementieren müssen und du lediglich Basisfunktionalität anbietest, sprich getter / setter ?

wäre super wenn du mir fix ein Beispiel posten könntest .
 

kaoZ

Top Contributor
Ok , ich fuchs mich langsam rein , das hier funktioniert zu testzwecken schomal soweit:

Hier die Action :

Java:
public class InvoiceAction extends AbstractAction {
	private static final long serialVersionUID = 1L;
	
	private JComponent parent, target;
	private JPanel content;
	
	public InvoiceAction(JComponent parent, JComponent target) {
		super("Rechnung");
		this.parent = parent;
		this.target = target;
		createContent();
	}
	
	private void createContent(){
		content = new JPanel();
		content.setBackground(Color.RED);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		target.add(content);
		target.validate();	
	}
	
	public JComponent getParent()				 {return this.parent;}
	public JComponent getTarget()				 {return this.target;}
}

und hier der der der aufruf in der View:

Java:
public class EditorView {
	
	JFrame frame;
	JPanel contentPane, sideBar, statusBar, printPanel;
	JMenuBar menuBar;
	JToolBar toolBar;
	
	public EditorView() {
		initialise();
		addComponents();
	}
	
	private void initialise(){
		frame = FrameFactory.createFrame(APP_TITLE, SCREEN_WIDTH, SCREEN_HEIGHT, JFrame.DISPOSE_ON_CLOSE, JFrame.MAXIMIZED_BOTH, null);
		
		contentPane	 = new JPanel(new BorderLayout());
		//contentPane.setBackground(Color.BLUE); <<-- für Testzwecke
		sideBar		 = new JPanel();
		statusBar	 = new JPanel();
		printPanel	 = new JPanel(new BorderLayout());
		//printPanel.setBackground(Color.GREEN); <-- für Testzwecke
		
		menuBar = createMenuBar();
		toolBar = createToolBar();
	}
	
	private JMenuBar createMenuBar(){
		JMenuBar bar = new JMenuBar();
		
		JMenu fileMenu, editMenu, optionMenu, searchMenu, windowMenu, helpMenu;
		
		fileMenu	 = new JMenu(MENUBAR_FILE);
			JMenu newFileMenu = new JMenu("Neu...");
				JMenuItem invoice	 = new JMenuItem(new InvoiceAction(menuBar, printPanel));  // <<----
				JMenuItem estimate	 = new JMenuItem();
				
				newFileMenu.add(invoice);
				newFileMenu.add(estimate);
				
			JMenuItem save		 = new JMenuItem();
			JMenuItem saveUnder	 = new JMenuItem();
			JMenuItem importFile = new JMenuItem();
			JMenuItem exportFile = new JMenuItem();
			JMenuItem close		 = new JMenuItem();
			
		fileMenu.add(newFileMenu);
		fileMenu.add(save);
		fileMenu.add(saveUnder);
		fileMenu.add(importFile);
		fileMenu.add(exportFile);
		fileMenu.add(close);
		
			
		
		
		editMenu	 = new JMenu(MENUBAR_EDIT);
		optionMenu	 = new JMenu(MENUBAR_OPTION);
		searchMenu	 = new JMenu(MENUBAR_SEARCH);
		windowMenu	 = new JMenu(MENUBAR_WINDOW);
		helpMenu	 = new JMenu(MENUBAR_HELP);

		
		bar.add(fileMenu);
		bar.add(editMenu);
		bar.add(optionMenu);
		bar.add(searchMenu);
		bar.add(windowMenu);
		bar.add(helpMenu);
		
		
		
		
		return bar;
	}
	
	private JToolBar createToolBar(){
		JToolBar bar = new JToolBar();
		  //TODO
		return bar;
	}
	
	private void addComponents(){
		frame.setJMenuBar(menuBar);
		frame.add(BorderLayout.CENTER, contentPane);
		
		contentPane.add(BorderLayout.CENTER, printPanel);
	}
	
	public void show(){
		frame.setVisible(true);
	}

}

Zudem schreibe ich grade den Code um und kapsel die Erstellung der Menu / toolbar und der der Panel in eingenen Methoden, anstatt in eigenen Klassen, ich würde jetzt für jede Aktion die ausgeführ werden soll, in Menu sowie Toolbar dann jeweils eine Action in einem Separaten Package erstellen.

Die Nächste Frage die sich mir stellt ist , wenn ich jetz über die Action dem printPanel ein neues JPanel zunzugefügt habe, dann ist dieses Panel "befüllt" wenn ich jetzt eine andere Action ausführe passiert nichts , auch nicht wenn ich über validate() neu validieren lasse:

das hier z.B

Java:
JMenuItem invoice	 = new JMenuItem(new InvoiceAction(menuBar, printPanel));
JMenuItem estimate	 = new JMenuItem(new EstimateAction(menuBar,printPanel));

Soblad ich die erste Aktion ausgeführt habe setze ich die hintergrundfarbe auf Grün, wenn ich jetzt aber die 2te Aktion ausführen möchte sollte er dementsprechend den inhalt neu zeichnen und mit dem aktuellen inhalt überlegen, das funktioniert aber nicht, auch nicht wenn ich über repaint() ein neuzeichnen anstoße.

oder muss ich hierzu noch eine Abfrage in der actionPerformed jeder Action ausführen , den panel erst leeren , und dann neu befüllen?

[EDIT]
ok, mit
Code:
removeAll();
funktioniert es
[/EDIT]

Dann könnte man doch z.B eine Action die zum Schließen des Frames zuständig ist, einfach so definieren , oder ?

Java:
public class CloseAction extends AbstractAction {
	private static final long serialVersionUID = 1L;

	private JFrame parent;
		
	public CloseAction(JFrame parent) {
		super("Schließen");
		this.parent = parent;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		getParent().dispose();
	}
	
	public JFrame getParent()				{return this.parent;}
}
 
Zuletzt bearbeitet:

Harry Kane

Top Contributor
Mit deiner aktuellen Version von InvoiceAction erzeugst du ein a) leeres JPanel und b) noch bevor es wirklich gebraucht wird.
Ich würde mir ein Interface PanelFactory erstellen mit mit einer Methode
Code:
JPanel createPanel();
und verschiedenen Implementiereungen, z. B. InvoicePanelFactory, die ein InvoicePanel zurückgibt. Die passende Instanz von PanelFactory könntest du an die Actions übergeben, und in der actionPerformed() die Methode createPanel der Factory aufrufen und dem target hinzufügen.
Ich würde target übrigens als Container deklarieren, damit du beispielsweise auch die Content Pane des JFrames übergeben kannst.
ZUr Frage nach der CloseAction; Jo, das müsste gehen.
 

kaoZ

Top Contributor
Mit deiner aktuellen Version von InvoiceAction erzeugst du ein a) leeres JPanel und b) noch bevor es wirklich gebraucht wird.

Das war ausschließlich um zu testen ob der Panel dem Container hinzugefügt wird, ich hab es jetzt soweit das ich in der View jeweils getter anbiete welche mir den jeweiligen Container zurückliefern, so kann ich dann einfach

Java:
JMenuItem invoice = new JMenuItem(new InvoiceAction(getContentPane(), getPrintPanel()));

Zu der Factory, klar könnte ich machen , der inhalt der jeweiligen panel ist allerdings fest definiert, das heißt der inhalt bleibt immer identisch, nur die daten ändern sich mit jeder "Rechnung".

wenn ich es über die Factory löse, müsste ich in der actionPerformed der Action ja dann letztendlich nurnoch die Factory um ein neues Panel bitten, das gleiche habe ich übrigends damit bezwecken wollen , die jeweiligen Views von JPanel abzuleiten und dann nurnoch beim hinzufügen zum Container zu instanzieren.

Alles in alles könnte ich ja jetzt mit den Einzelnen Actions ja auch wieder auf das Schema umsteigen, den View aus Bausteinen zusammenzusetzen die ich in Separaten Klassen definiere, und dann beim Erzeugen des Views in die jeweiligen bereiche der ContentPane (JPanel )setze.

Ich würde target übrigens als Container deklarieren, damit du beispielsweise auch die Content Pane des JFrames übergeben kannst.

Dazu müsste ich ja letztendlich nur eine Referenz auf die Oberklasse Container anstelle von JComponent in den einzelnen Actions halten , oder täusche ich mich jetzt, JComponent ist ja auch eine Subklasse von Container .
 

kaoZ

Top Contributor
So ich werd das jetzt nochmal alles überarbeiten , dementsprechend werde ich auch Schnittstellen zur Kommunikation zwischen View , Model und Controller anbieten, um eine losere Kopplung zu erreichen und mich nicht auf Konkrete Implementierungen festlegen zu müssen,

danke erstmal für den Rat mit den Actions, ich werde dies in Zukunkt für MenuBars / Toolbars anwenden und überall dort wo mehrere Auslöser für die gleichen Aktionen existieren.

Die letztem Fragen die bleiben ist :

1.ist eine zusätzliche Factory für jedes zu erstellende Panel nicht schon irgendwie Overengineering ?

2.Was genau meinst du mit Säulen ^^

3.Wie würdest du die einzelnen Schnittstellen herausfaktorieren bzw. wie würdest du vorgehen

angenommen ich biete eine mit eingeschränkter sichtbarkeit gültige Methode an welche dem printPanel einen Content in form eines JComponents zuweisen soll :

Java:
public void setPrintPanelContent(JComponent content){...}

und würde lediglich in einer Schnittstelle eine öffentliche Business Methode anbieten welche sich vom Abstraktionsniveau höher ansiedelt und auch die auch Implementierungsdetails vor Klienten verbirgt:

Java:
public void setContent(JComponent content);

diese würde dann in ihrer Konkreten Implementierung (in der Klasse EditorView) lediglich die
konkretiesierten Methoden nutzen und per delegation den content setzen.

Java:
@Override
public void addContent(JComponent content){
  setPrintPanelContent(content);
}

und

4. wie würdest du diese Schnittstellen benennen ?

Für den
Code:
EditorView - EditorViewIF ?

oder würdest du die View welche das Programm Optisch darstellt allgemein anders benennen ?

[EDIT]
Zudem hast du recht, ich sollte die ToolBar und die MenuBar nicht ableiten , da ich diese Klassen ja nicht um Funktionalität erweitere.

Allerdings könnte ich ja die Toolbar totzdem in einer Separaten Klasse realisieren, und einfach eine Referenz auf eine JToolbar halten, welche ich dann einfach initialisiere und dann in meiner View instanziere, dies würde den Source Code der View nicht so aufblähen und das ganze übersichtlicher gestalten , wäre das vom Design her denn sinnvoller ?

sprich so in der Art:

Java:
public class MyToolBar{

  JToolBar toolBar;

public MyToolBar(){
  this.toolBar = new JToolBar();
  init();
  addComponents();
}

// usw...

public JToolBar getToolBar()      {return this.toolBar;}
}
[/EDIT]
 
Zuletzt bearbeitet:

Harry Kane

Top Contributor
1.ist eine zusätzliche Factory für jedes zu erstellende Panel nicht schon irgendwie Overengineering ?

2.Was genau meinst du mit Säulen ^^

3.Wie würdest du die einzelnen Schnittstellen herausfaktorieren bzw. wie würdest du vorgehen
zu 1: Ist wie so vieles Geschmackssache. Sieht für mich zumindest besser aus als die folgenden Alternativen:
a) Die JPanels komplett in der Action zu konfigurieren. Widerspricht meiner Meinung nach dem Prinzip der Aufgabenteilung. Eine Action soll eine Aktion auslösen und nicht die komplette Implementierung der Aktion umfassen, damit die Implementierung auch ausserhalb der Action verwendbar ist.
b) Für jedes Panel sowas wie
Code:
BlaPanel extends JPanel{}
zu schreiben. Da führt dazu, daß eventuell für alle Dialoge durchzuführende Konfigurationsarbeit mehrfach erledigt werden muß. Ein Factory kann einem solche Konfigurationsarbeiten abnehmen.
Was mir vorschwebt wäre sowas wie:
Java:
public abstract class PanelFactory {
    private PanelFactory(){
        
    }
    public abstract JPanel createPanel();
    protected void configure(JPanel p){
        //Layout setzen
        //ev. ständig wiederkehrende Components setzen
    }
    public static PanelFactory DIALOG = new PanelFactory(){
        public JPanel createPanel(){
            JPanel panel = new JPanel();
            configure(panel);
            return panel;
        }
    };
}

zu 2: "Säule" ist synonym zu "Grundidee", "Ansatz" etc.

zu 3.: Uff. Die Frage ist mir viel zu allgemein formuliert.
Zu deinem Beispiel mit
Code:
public void setContent(JComponent content);
in einem "Oberinterface",
Code:
setPrintPanelContent(JComponent content)
in einem "Unterinterface" und
Code:
addContent(JComponent content)
in einer konkreten Implementierung. Wenn deine setXXXContent-Methoden öffentlich sind, warum brauchst du in deiner Implementierung noch eine dritte Methode. Ich könnte eventuell verstehen, wenn die öffentliche
Code:
setContent(JComponent)
Methode die spezielle
Code:
addContent(JComponent)
aufruft, aber nicht umgekehrt.
 

kaoZ

Top Contributor
Ich hatte mich verschrieben :)

Es sind natürlich nur 2 Methoden, eine Öffentliche in der Schnittstelle die Funktionalitäten abstrakt deklariert, und die Konkretisierung in der view, welche dann den speziellen Content setzt

Java:
public interface EditorViewIF {

  public void addContent (JComponent content, JComponent target);
}

Welche dann in einer Konkreten Implementierung eine in ihrer Sichtbarkeit reduzierte Methode aufruft, und dementsprechend die Komponente übergibt.

Dann wäre es nur möglich den Content über die Schnittstelle zu setzen und die Implementierungsdetails bleiben nach außen hin verborgen.

Entschuldige bitte evtl. Rechtschreibfehler, T9 sei Dank, ich schreibe vom Handy aus ;)

Zu der Sache mit den JPanel, diese wollte ich keines Wegs in den Actions definierten, die War lediglich um zu sehen ob Funktionalität gegeben ist :)
 
Zuletzt bearbeitet:

kaoZ

Top Contributor
Ich hab mir heute Nacht nochmal gedanken darüber gemacht, und es nach folgendem Ansatz versucht

Die Action :

Java:
public class EstimateAction extends AbstractAction {
	private static final long serialVersionUID = 1L;
	
	private JComponent target;
	
	public EstimateAction(JComponent target) {
		super("Kostenvoranschlag");
		this.target = target;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		target.removeAll();
		target.add(ContentFactory.createEstimateContent());
		target.validate();
	}
}

Die Factory die Später die JPanel erzeugt :

Java:
public class ContentFactory {

	public ContentFactory() {}
	
	public static JComponent createInvoiceContent(){
		return null;
	}
	
	public static JComponent createEstimateContent(){
		
		//Ausschließlich um zu testen ob der Content gesetzt wird
		
		JComponent component = new JPanel();
		
		component.setBackground(Color.CYAN);
		
		return component;
	}
}

und der dazu gehörende Aufruf in der Gui:

Java:
JMenuItem estimate = new JMenuItem(new EstimateAction(printPanel));

mal abgesehen davon das hier noch kein Controller zum Einsatz kommt sollte das von der Zuständigkeitstrennung und der Kapselung doch schon eher in die Richtung deines Vorschlags gehen oder ?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Problem mit der Anzeige von jLabel. Unlesbar wenn der Text geändert wird. AWT, Swing, JavaFX & SWT 28
H 2D-Grafik Problem mit Paint AWT, Swing, JavaFX & SWT 1
S Layout - Problem AWT, Swing, JavaFX & SWT 1
Tassos JavaFX/Problem mit der Maussteuerung in Stackpane AWT, Swing, JavaFX & SWT 7
sserio Java Fx - Problem AWT, Swing, JavaFX & SWT 3
A Problem Spiel auf Panel der GUI zu bringen AWT, Swing, JavaFX & SWT 1
A JavaFX Controller Problem AWT, Swing, JavaFX & SWT 1
TheWhiteShadow JavaFX ListView Problem beim Entfernen von Elementen AWT, Swing, JavaFX & SWT 1
E LayoutManager Welcher Layout-Mix löst mein Problem? AWT, Swing, JavaFX & SWT 3
Umb3rus JavaFX Problem mit PropertyValueFactory: can not read from unreadable property AWT, Swing, JavaFX & SWT 1
T Problem mit paintComponent() AWT, Swing, JavaFX & SWT 17
AmsananKING Java Menü-Problem AWT, Swing, JavaFX & SWT 1
K JavaFX Resizing-Problem beim BorderLayout (Center Component) beim Arbeiten mit mehreren FXMLs AWT, Swing, JavaFX & SWT 2
G Instance OF Problem AWT, Swing, JavaFX & SWT 9
FrittenFritze Ein Problem mit der CSSBox, die Größe wird nicht angepasst AWT, Swing, JavaFX & SWT 5
M Problem mit dem Anzeigen von Frames im Vordergrund AWT, Swing, JavaFX & SWT 5
Badebay Problem mit JButton AWT, Swing, JavaFX & SWT 2
newJavaGeek Grid-Layout problem AWT, Swing, JavaFX & SWT 7
J JavaFX Löschen im Tabelview macht Problem AWT, Swing, JavaFX & SWT 15
JavaTalksToMe JavaFx ExekutorService Problem AWT, Swing, JavaFX & SWT 2
Zrebna Problem bei Eventhandling (Value soll nach jedem erneutem Klick gelöscht werden) AWT, Swing, JavaFX & SWT 4
B Problem mit JavaFX AWT, Swing, JavaFX & SWT 5
J css Problem AWT, Swing, JavaFX & SWT 5
B JavaFX habe mein Problem fett markiert AWT, Swing, JavaFX & SWT 2
A Swing Filter-Problem AWT, Swing, JavaFX & SWT 1
temi JavaFX Problem mit IntelliJ und JavaFx 11 unter XUbuntu AWT, Swing, JavaFX & SWT 3
L Java FX Problem mit Ubuntu 18 und JavaFx AWT, Swing, JavaFX & SWT 27
H JTable TableCellEditor-Problem AWT, Swing, JavaFX & SWT 0
kodela Swing Problem mit Warten-Dialog AWT, Swing, JavaFX & SWT 16
B JavaFx Scene Builder Problem AWT, Swing, JavaFX & SWT 2
B [Problem] Java öffnet Word-Datein nicht AWT, Swing, JavaFX & SWT 14
T DataBinding Problem AWT, Swing, JavaFX & SWT 5
Blender3D Problem mit € Symbol Font Gotham Windows 10 Swing AWT, Swing, JavaFX & SWT 11
T Problem mit JTable Sortierung AWT, Swing, JavaFX & SWT 2
J Problem mit Platfrom run later AWT, Swing, JavaFX & SWT 15
J Problem mit Platfrom run later AWT, Swing, JavaFX & SWT 0
D Swing SwingUtils / Thread Problem AWT, Swing, JavaFX & SWT 3
L JavaFX Problem beim Aufrufen einer Methode AWT, Swing, JavaFX & SWT 5
T Swing Problem mit Datum und FormattedTextField AWT, Swing, JavaFX & SWT 2
S AWT Java print dialog Problem AWT, Swing, JavaFX & SWT 0
olfibits JavaFX Problem mit HTMLEditor AWT, Swing, JavaFX & SWT 0
W SWT hover-background-problem with first column in TreeViewer AWT, Swing, JavaFX & SWT 0
M Problem mit Add JScrollPane AWT, Swing, JavaFX & SWT 25
Mario1409 Swing JTextArea scroll Problem AWT, Swing, JavaFX & SWT 0
N Swing Problem mit loop AWT, Swing, JavaFX & SWT 2
S Swing Problem mit Button und ActionListener AWT, Swing, JavaFX & SWT 5
S Swing & Clean und build Problem AWT, Swing, JavaFX & SWT 12
S JLabel setText() Problem AWT, Swing, JavaFX & SWT 6
I 2D-Grafik Problem beim Ändern der Farbe eine 2d Objekts AWT, Swing, JavaFX & SWT 3
G Swing Splitpane Problem AWT, Swing, JavaFX & SWT 1
F Problem mit der FXML Rectangle Shape AWT, Swing, JavaFX & SWT 2
N JavaFX Stranges Problem mit der Autoscroll-Eigenschaft von Textareas AWT, Swing, JavaFX & SWT 0
E Java FX FXML Problem mit html Scriptausführung AWT, Swing, JavaFX & SWT 2
J JavaFX Intersect Problem mit Shapes AWT, Swing, JavaFX & SWT 10
R JavaFX MediaPlayer AVI-Problem AWT, Swing, JavaFX & SWT 1
M Swing Problem mit ListCellRenderer AWT, Swing, JavaFX & SWT 7
D Problem mit JTable AWT, Swing, JavaFX & SWT 1
F GUI Auflösung ändern - Koordianten und Proportions Problem AWT, Swing, JavaFX & SWT 21
J Problem mit Button darstellung AWT, Swing, JavaFX & SWT 23
M Problem mit Layoutmanagern... Hilfe wäre sehr nett. AWT, Swing, JavaFX & SWT 2
S 2D-Grafik Problem mit Variablen AWT, Swing, JavaFX & SWT 4
7 JavaFX Problem beim Zeichnen eines Dreiecks in einem GUI AWT, Swing, JavaFX & SWT 6
M Swing AttributiveCellTableModel addRow() Problem AWT, Swing, JavaFX & SWT 1
J Swing Problem mit Graphics Methode AWT, Swing, JavaFX & SWT 4
N JavaFX Problem mit table multiple selection AWT, Swing, JavaFX & SWT 5
K CheckBox Problem AWT, Swing, JavaFX & SWT 5
Grevak DisplayMode Problem seit Windows 10 AWT, Swing, JavaFX & SWT 2
S Swing Eigene JComboBox Problem! AWT, Swing, JavaFX & SWT 1
B Swing Problem mit Bildpfad AWT, Swing, JavaFX & SWT 4
N Swing Problem beim Scrollen mit JScrollPane AWT, Swing, JavaFX & SWT 6
V Graphics g - drawOval problem mit background AWT, Swing, JavaFX & SWT 1
C AWT Problem mit Protokol Fenster AWT, Swing, JavaFX & SWT 0
M Swing pack() Problem mit Taskleiste AWT, Swing, JavaFX & SWT 4
N Swing Choice- Problem! AWT, Swing, JavaFX & SWT 8
Q "AWT-EventQueue-0" Exception Problem AWT, Swing, JavaFX & SWT 4
D jButton Problem, ein Rieser Button bedeckt das ganze frame AWT, Swing, JavaFX & SWT 1
A Problem: repaint() - Schleife AWT, Swing, JavaFX & SWT 3
J Anfänger GUI Problem bei der Ausführung eines sehr einfachen Programms AWT, Swing, JavaFX & SWT 2
P AWT Problem mit Platzierung (GridBagLayout) AWT, Swing, JavaFX & SWT 2
N Swing JTree Problem beim erstellen der Knoten AWT, Swing, JavaFX & SWT 0
N Swing CardLayout: Problem beim Wechsel zwischen den JPanels AWT, Swing, JavaFX & SWT 3
A Mini-Menu-Schriften. Ein Problem bei hohen DPI Zahlen AWT, Swing, JavaFX & SWT 2
Z Canvas in Frame einfügen. Problem mit 4-Gewinnt AWT, Swing, JavaFX & SWT 1
C Thread-/ Simulations- Problem AWT, Swing, JavaFX & SWT 18
G Swing Setvisible problem AWT, Swing, JavaFX & SWT 1
J JTabbedPane: close Button Problem AWT, Swing, JavaFX & SWT 2
Tom299 JavaFX -> fxmlLoader -> getResourceAsStream Problem AWT, Swing, JavaFX & SWT 1
T Problem: ComboBox und addItem AWT, Swing, JavaFX & SWT 5
M JTextArea wird nicht aktualisiert (ActionListener-Problem) AWT, Swing, JavaFX & SWT 1
T LayoutManager LookAndFeel-Problem AWT, Swing, JavaFX & SWT 4
F Problem mit Implementierung von Kollisionsabfrage AWT, Swing, JavaFX & SWT 5
vodkaz (javafx) Image Problem AWT, Swing, JavaFX & SWT 2
T Problem beim Zeichnen von Rechteck AWT, Swing, JavaFX & SWT 3
B JavaFX Problem bei Kamera / Group, gesamte Scene bewegt sich mit AWT, Swing, JavaFX & SWT 0
L Swing Vier Gewinnt Problem AWT, Swing, JavaFX & SWT 2
Z GUI-Problem, finde meinen Fehler nicht! AWT, Swing, JavaFX & SWT 11
B JavaFX KeyEvent und Canvas draw Problem AWT, Swing, JavaFX & SWT 9
R Swing Problem: IOException bei ActionListener AWT, Swing, JavaFX & SWT 1
GianaSisters JFrame mit JInternalFrames, Keylistener-Problem AWT, Swing, JavaFX & SWT 9
Q JList Update Problem AWT, Swing, JavaFX & SWT 1

Ähnliche Java Themen

Neue Themen


Oben