Swing verschachteltes GUI: repaint() ändert mehr als nur gewünschte Component

baphomet13

Mitglied
Liebe Alle,

in meiner GUI Klasse nutze ich ein ziemlich verschachteltes Layout.

Code:
 _____________________________________________________
| (1) Menüleiste                                      |
 -----------------------------------------------------
| (2) Toolbar                                         |
 -----------------------------------------------------
|                                                     |
| (3) Steuerungselemente (Buttons/Dropdownlisten)     |
|                                                     |
 -----------------------------------------------------
|                                                     |
| (4) Anzeigefenster (je nach Auswahl in              |
| den Steuerungselemente JTextField oder JTable)      |
|                                                     |
 -----------------------------------------------------

In (4) (CardLayout) habe ich wiederum ein JPanel (peopleSearchCard(new BorderLayout()). Im CENTER von peopleSearchCard habe ich ein JPanel namens peopleSearchResults, im WEST ein Formular in einem verschachtelten JPanel der Methode peopleSearchForm() (gibt ein JPanel mit FlowLayout zurück). In diesem Formular habe ich einen JButton butPeopleSearch samt ActionListener, der nun einfach ein JLabel in peopleSearchResults hinzufügen soll und letzteres JPanel dann repaint()et.

Kurze "grafische" Übersicht von (4):

Code:
 _____________________________________________________
| peopleSearchForm() |                                |
| Formular mit       |  peopleSearchResults           |
|   JButton          |                                |

Das funktioniert auch, allerdings wird nach Klick nicht nur das JPanel peopleSearchResults verändert (wie gewollt), sondern auch in (3), den Steuerungselementen (toolPanel, ein JPanel mit CardLayout()), die Card journalsCard angezeigt.

"Einfache" Frage: warum? Ich versteh's nicht... 🙁

Hier der Code:

Java:
import javax.swing.*;
import javax.swing.border.EmptyBorder;

import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import java.util.List;

public class Gui extends JFrame implements ActionListener {
	
    /* Class Variables */
	private JLabel testlab; // Test-Label
	private JPanel mainPanel, toolPanel, outputPanel, journalsCard, defaultToolCard, defaultOutputCard, tableCard, peopleCard, peopleSearchCard, peopleSearchResults, peopleSearchForm;
	final static String PEOPLE = "People Tools Call";
	final static String PEOPLESEARCH = "People Search Call";
	final static String PRINTTABLECALL = "Card One Call String"; // *REMOVE* CARD1-3CALL -> Placeholders
	final static String JOURNALS = "Journals Tools Call";
	final static String CARD2CALL = "Card Two Call String";
	final static String CARD3CALL = "Card Three Call String";
	final static String DEFAULTCALL = "Default Call String";
	final static String DEFAULTOUTPUTCALL = "Default Output Call String";
	final static String WELCOME = "Welcome!";
	static DbOperations db;
	private ResultSet rs;
    	
    public Gui ()
    {
    	super("Titel");
        
    	//Create and set up the window.
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        setJMenuBar(createMenuBar());
        setContentPane(createContentPane());
        
        // Create and set up the tool bar
        JToolBar toolb = new JToolBar();

        JButton b1 = new JButton("People");
        b1.addActionListener(this);
        b1.setActionCommand("bPeople");

        JButton b2 = new JButton("Journals");
        b2.addActionListener(this);
        b2.setActionCommand("bJournals");

        toolb.add(b1);
        toolb.add(b2);

        getContentPane().add(BorderLayout.NORTH,toolb);
        
        // mainPanel in CENTER of getContentPane
        mainPanel = new JPanel(new BorderLayout());
        getContentPane().add(BorderLayout.CENTER,mainPanel);
        
        // Cards for toolPanel
        // Set default Welcome card
        defaultToolCard = new JPanel(new BorderLayout());
        defaultToolCard.setBackground(Color.LIGHT_GRAY);
        JLabel labWelcome = new JLabel(WELCOME);
        labWelcome.setVerticalAlignment(JLabel.CENTER);
        labWelcome.setHorizontalAlignment(JLabel.CENTER);
        defaultToolCard.add(labWelcome);

        // Card for People Tools
        peopleCard = new JPanel();
        
        JButton bPrnPeopTab = new JButton("Print Table 'People'");
        bPrnPeopTab.addActionListener(this);
        bPrnPeopTab.setActionCommand("cmdPrnPeopTab");

        JButton bPeopleSearch = new JButton("Search for People");
        bPeopleSearch.addActionListener(this);
        bPeopleSearch.setActionCommand("cmdSearchPeople");

        peopleCard.add(bPeopleSearch);
        peopleCard.add(bPrnPeopTab);
        // Card for Journal Tools
        journalsCard = new JPanel();
        journalsCard.setBackground(Color.orange);
//        journalsCard.add();
        
        // toolPanel with CardLayout in NORTH of mainPanel
        toolPanel = new JPanel(new CardLayout());
        toolPanel.add(defaultToolCard,DEFAULTCALL); // Add's the default JPanel with default JLabel (Welcome text) - ALWAYS FIRST!
        toolPanel.add(peopleCard,PEOPLE);
        toolPanel.add(journalsCard,JOURNALS);
        mainPanel.add(BorderLayout.NORTH,toolPanel);
        
        // Create default OutputCard with logo
        JLabel logoPanel = new JLabel(new ImageIcon("./images/logo.png"));
        logoPanel.setVerticalAlignment(JLabel.CENTER);
        logoPanel.setHorizontalAlignment(JLabel.CENTER);
        
        // Cards for outputPanel
        defaultOutputCard = new JPanel(new BorderLayout());
        defaultOutputCard.setBackground(Color.WHITE);
        defaultOutputCard.add(logoPanel);
        tableCard = new JPanel(); // *REMOVE* card1-3 -> Placeholders
        peopleSearchCard = new JPanel(new BorderLayout());
        JPanel card3 = new JPanel();
        
        // outputPanel w/ CardLayout in CENTER of mainPanel 
        outputPanel = new JPanel(new CardLayout());
        outputPanel.add(defaultOutputCard,DEFAULTOUTPUTCALL); // *REMOVE* card1-3 -> Placeholders
//        outputPanel.add(tableCard,CARD1CALL); // *REMOVE* card1-3 -> Placeholders
        outputPanel.add(peopleSearchCard,PEOPLESEARCH);
        outputPanel.add(card3,CARD3CALL);
        mainPanel.add(BorderLayout.CENTER,outputPanel);
 
        //Display the window.
        pack();
        setExtendedState(getExtendedState()|JFrame.MAXIMIZED_BOTH);
        setVisible(true);

    }//end constructor Gui

    public JMenuBar createMenuBar() {
        JMenuBar menuBar;
        JMenu filemenu, filesubmenu, helpmenu;
        JMenuItem menuItem, exitItem;

        //Create the menu bar.
        menuBar = new JMenuBar();

        //Build the file menu.
        filemenu = new JMenu("File");
        filemenu.setMnemonic(KeyEvent.VK_F);
        filemenu.getAccessibleContext().setAccessibleDescription("The file menu");
        
        // Build the help menu
        helpmenu = new JMenu("Help");
        helpmenu.setMnemonic(KeyEvent.VK_H);
        helpmenu.getAccessibleContext().setAccessibleDescription("The help menu");
        
        // Add menus to menu bar
        menuBar.add(filemenu);
        menuBar.add(Box.createHorizontalGlue()); // Moves Help menu to the far right in the menu bar
        menuBar.add(helpmenu);

        //a group of JMenuItems
        menuItem = new JMenuItem("Do",KeyEvent.VK_T);
        menuItem.addActionListener(this);
        menuItem.setActionCommand("do");
        exitItem = new JMenuItem("Exit",KeyEvent.VK_X);
        exitItem.addActionListener(this);
        exitItem.setActionCommand("exit");
        exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
        
        //a submenu
        filemenu.addSeparator();
        filesubmenu = new JMenu("A submenu");
        filesubmenu.setMnemonic(KeyEvent.VK_S);

        menuItem = new JMenuItem("An item in the submenu");
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
        filesubmenu.add(menuItem);

        menuItem = new JMenuItem("Another item");
        filesubmenu.add(menuItem);
        filemenu.add(filesubmenu);

        // Add Menu Items
        filemenu.add(menuItem);
        filemenu.add(exitItem);

        return menuBar;
    } // end method createMenuBar
    
    public Container createContentPane() {
        //Create the content-pane-to-be.
        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.setOpaque(true);
        return contentPane;
    } // end method createContentPane


	private JPanel peopleSearchForm() {
        peopleSearchForm = new JPanel(new FlowLayout(3,20,0));
        
        JPanel peopleSearchInline = new JPanel(new GridLayout2(5, 2, 10, 10));
        
        //Create and add the components.
        JLabel labName = new JLabel("Name: ",4); // 4 = RIGHT
        JTextField txtFieldName = new JTextField("Name", 15);
        JLabel labCity = new JLabel("City: ",4);
        JTextField txtFieldCity = new JTextField("City", 15);
        JLabel labCountry = new JLabel("Country: ",4);
        JTextField txtFieldCountry = new JTextField("Country", 15);
        JLabel labJournalCode = new JLabel("Journal Code: ",4);
        JTextField txtFieldJournalCode = new JTextField("Journal Code", 15);
        JButton butPeopleSearch = new JButton("Search");
        butPeopleSearch.addActionListener(this);
        butPeopleSearch.setActionCommand("cmdPeopleSearchForm");
        peopleSearchInline.add(labName);
        peopleSearchInline.add(txtFieldName);
        peopleSearchInline.add(labCity);
        peopleSearchInline.add(txtFieldCity);
        peopleSearchInline.add(labCountry);
        peopleSearchInline.add(txtFieldCountry);
        peopleSearchInline.add(labJournalCode);
        peopleSearchInline.add(txtFieldJournalCode);
        peopleSearchInline.add(new JLabel());
        peopleSearchInline.add(butPeopleSearch);

        peopleSearchForm.add(peopleSearchInline);
        
		return peopleSearchForm;
	} // end method peopleSearchForm()
       

	public void actionPerformed(ActionEvent e) {
		if ("bPeople".equals(e.getActionCommand())) {
			CardLayout cl = (CardLayout)(toolPanel.getLayout());
	        cl.show(toolPanel, PEOPLE);
		}
		if ("bJournals".equals(e.getActionCommand())) {
			CardLayout cl = (CardLayout)(toolPanel.getLayout());
	        cl.show(toolPanel, JOURNALS);
		}
		if ("cmdSearchPeople".equals(e.getActionCommand())) {
			peopleSearchResults = new JPanel();
			peopleSearchResults.setBackground(Color.pink);
			testlab = new JLabel("SEARCH RESULTS HERE!");
			peopleSearchResults.add(testlab);
			peopleSearchCard.add(BorderLayout.WEST,peopleSearchForm());
			peopleSearchCard.add(BorderLayout.CENTER,peopleSearchResults);
			outputPanel.add(peopleSearchCard,PEOPLESEARCH);
			CardLayout cl = (CardLayout)(outputPanel.getLayout());
	        cl.show(outputPanel, PEOPLESEARCH);
		}
		if ("cmdPrnPeopTab".equals(e.getActionCommand())) {
			JTextArea text = new JTextArea(); //TODO: Make wrapped in JScrollPane
			db = new DbOperations();
			db.loadDbDriver();
			try {
				rs = db.printTable();
			    ResultSetMetaData md = rs.getMetaData();
			    int count = md.getColumnCount();
			    for (int i=1; i<=count; i++) {
			    	text.append(md.getColumnLabel(i) + " || ");
			      }
			    text.append("\n");
			    while (rs.next()) {
			    	for (int i=1; i<=count; i++) {
			    		text.append(rs.getString(i) + " || ");
			        	}
			      text.append("\n");
			      }
				outputPanel.add(text,PRINTTABLECALL);
				CardLayout cl = (CardLayout)(outputPanel.getLayout());
		        cl.show(outputPanel, PRINTTABLECALL);
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		if ("cmdPeopleSearchForm".equals(e.getActionCommand())) {
			testlab = new JLabel("YOU HAVE RESULTS!");
			peopleSearchResults.add(testlab);
			peopleSearchResults.repaint();
			CardLayout cl = (CardLayout)(toolPanel.getLayout());
	        cl.show(toolPanel, JOURNALS);
		}
		if ("exit".equals(e.getActionCommand())) {
			System.exit(0);
		}
		
	} // end method actionPerformed()


} // end class Gui

Wäre *sehr* dankbar für hilfreiche Tips!
Herzlichen Dank im Voraus & Grüße,
B13
 
Argh:

[JAVA=264]
CardLayout cl = (CardLayout)(toolPanel.getLayout());
cl.show(toolPanel, JOURNALS); // -> toolPanel!
[/code]

NATÜRLICH ändert sich das toolPanel. Sag ich "ihm" ja extra. :bloed:

Aber eine andere Frage (oder soll das in einen neuen Thread?):
Ist es sinnvoller, das Results-"Fenster" als Card in einem CardLayout zu machen, oder jeweils zu repaint()en (or zu revalidate()n)? Dies in punkto Rechenzeit bzw. Programmieraufwand?

Heißen Dank für Hinweise!

Grüße,
B13
 
Ohne den Aufbau von CardLayout zu kennen (wie es intern abläuft) schätze ich, dass es im Grunde nichts anderes machen wird, als repainten. Also gleich auf das einfachere setzen, macht den Code hübscher und bugunfanfälliger.
 
m.E ist es sinnvoller bei einem Suchergebnis die Card zu verändern und evtl. dann repaint(), und/oder validate() aufzurufen, als eine neue Card zu basteln. Der Vorteil von Card-Layout ist ja der, dass die "Cards" ja vor der Anzeige "gebaut" werden und dann nur noch mittels der show-Methode angezeigt werden.
Dieses Verhalten bietet bspw bei Bildern einen Vorteil gegenüber dem Laden von Bildern erst nach einer User-Aktion. Bei Sucheregebnissen, wie du sie hier hast würde ich einfach eine Card verändern.
 

Zurück
Oben