2010-10-27 5 views
10

Für ein Schulprojekt muss ich eine einfache malen Anwendung, die Linien, Ovale und Rechtecke zeichnen kann.Swing: Link Umschalttasten zusammen mit einer Tastengruppe, zusammen mit entsprechenden Menüpunkten

Die Zuweisung gibt an, dass ich die Symbolleistenschaltflächen und Menüelemente für jede Art von Form benötigen.

Ich möchte ein wenig darüber hinaus gehen, indem Sie die Schaltflächen JToggleButtons in der Symbolleiste und die Menüoptionen JRadioButtonMenuItems. Darüber hinaus möchte ich, dass, wenn Sie eine der Symbolleistenschaltflächen auswählen, die anderen abgewählt werden, der entsprechende Menüeintrag ausgewählt und die anderen Menüpunkte abgewählt werden. Gleiches für die Auswahl eines der Menüpunkte.

Ich weiß, dass ich AbstractButton mit einem ButtonGroup gruppieren kann, aber ich bin nicht sicher, ob das der richtige Weg ist, denn obwohl es eine "Gruppe" von Knöpfen gut behandelt, bin ich nicht sicher, dass es zwei behandeln kann parallele Gruppen.

Ohne ButtonGroup würde bedeuten, dass in jedem der 6 Event-Listener ich die anderen Schaltflächen manuell deaktivieren müsste, und jedes Paar würde den gleichen Code aufrufen, um den Formentyp festzulegen.

Ich könnte auch zwei ButtonGroup s, eins für das Menü, eins für die Symbolleiste, aber dann muss ich auch Formtyp Einstellungscode zu duplizieren.

In beiden Situationen gehe ich auch das Risiko ein, dass das Menü eine Schaltfläche setzt, die einen Menüeintrag setzt, der eine Schaltfläche ad infintum setzt.

Was ist der beste Weg, um dieses Problem anzugehen?

(Bonuspunkte für die Möglichkeit, das Problem mit den Netbeans GUI-Designern zu lösen, es ist nur einfacher)

+5

Bonuspunkte für den Einsatz ohne GUI-Designer. Sie verbringen Ihre Zeit damit, Java zu lernen, das tragbar ist, eher die IDE, die es nicht ist. – camickr

+0

@camickr - Ich bevorzuge es tatsächlich, Textmate und das Terminal über eine IDE zu verwenden, es ist nur so, dass der GUI-Designer die Dinge viel schneller macht * SO *. Mein Punkt war, dass ich es lieber im Designer lösen würde, um zu sehen, wie es gemacht wurde, als sich damit zu beschäftigen, den automatisch generierten Code zu bearbeiten und stundenlang herauszufinden, warum kleine Dinge nicht funktionieren. –

Antwort

18

Die Action Schnittstelle ist ein wirksamer Ansatz „wenn Sie zwei oder mehr Komponenten, die die gleiche Funktion erfüllen,“ wie in How to Use Actions diskutiert. Insbesondere würde ein Action Ihren Tasten und Menüpunkten ermöglichen, den gleichen Code zu verwenden.

Nachtrag: Das folgende Beispiel zeigt, wie sich JMenu und JToolBar die gleichen Action für jede von mehreren Dateien teilen können.

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.io.File; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JMenuItem; 
import javax.swing.JToolBar; 

/** @see http://stackoverflow.com/questions/4038605 */ 
public class FileMenu { 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       new FileMenu().create(); 
      } 
     }); 
    } 

    void create() { 
     File userDir = new File(System.getProperty("user.dir")); 
     File[] files = userDir.listFiles(); 

     JMenu menu = new JMenu("Recent Files"); 
     JToolBar toolBar = new JToolBar(JToolBar.VERTICAL); 
     JLabel label = new JLabel(" ", JLabel.CENTER); 
     for (File f : files) { 
      if (f.isFile() && !f.isHidden()) { 
       RecentFile rf = new RecentFile(f, label); 
       menu.add(new JMenuItem(rf.getAction())); 
       toolBar.add(rf.getAction()); 
      } 
     } 
     JMenuBar menuBar = new JMenuBar(); 
     menuBar.add(menu); 

     JFrame f = new JFrame("FileMenu"); 
     f.setJMenuBar(menuBar); 
     f.add(toolBar, BorderLayout.CENTER); 
     f.add(label, BorderLayout.SOUTH); 
     f.pack(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 
} 

class RecentFile extends AbstractAction { 

    private final File file; 
    private final JLabel label; 

    public RecentFile(final File file, final JLabel label) { 
     this.file = file; 
     this.label = label; 
     this.putValue(Action.NAME, file.getName()); 
     this.putValue(Action.SHORT_DESCRIPTION, file.getAbsolutePath()); 
    } 

    public void actionPerformed(ActionEvent e) { 
     label.setText(file.getName()); 

    } 

    public Action getAction() { 
     return this; 
    } 
} 
+3

+1, Aktionen sind genauso einfach zu schreiben wie ein ActionListener, bieten aber weit mehr allgemeine Funktionalität. – camickr

+2

Können Sie erklären, warum Sie (rf.getAction()) und nicht nur (rf) zur Symbolleiste in diesem Code hinzufügen: 'toolBar.add (rf.getAction());', sowie in der Zeile darüber? –

+2

@userunknown: Gute Frage; Es sieht so aus, als hätte ich das von einem anderen Beispiel übernommen, das eher Komposition als Erweiterung verwendet. – trashgod