[JAVA] menubar in een Panel

Pagina: 1
Acties:
  • 129 views sinds 30-01-2008
  • Reageer

  • Zynth
  • Registratie: September 2001
  • Laatst online: 29-07 15:30
Ik heb pas een vraag gesteld over een grafisch venster.
Mij werdt toen aangeraden om het met Panels te doen.
Maar nu zit ik met een probleem met de menubar:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import java.awt.*;
import java.awt.event.*;
// Hoofdletter voor klassenaam
public class ComposeMail extends Panel
{
    // Gebruik 1 declaratie per regel

    private TextField toField;
    private TextField fromField;
    private TextArea messageField;
    private MenuItem exitMenuItem;
    private MenuItem sendMenuItem;
    private MenuItem resetMenuItem;
    private MenuItem aboutMenuItem;

    private CloseAction closeAction;

    public ComposeMail(Window window)
    {
        super(new BorderLayout());

        MenuBar menuBar = new MenuBar();
        Menu fileMenu   = new Menu("File");
        fileMenu.add(sendMenuItem = new MenuItem("Send"));
        fileMenu.add(resetMenuItem = new MenuItem("Reset"));
        fileMenu.add(exitMenuItem = new MenuItem("Exit"));
        menuBar.add(fileMenu);
        Menu aboutMenu  = new Menu("Help");
        aboutMenu.add(aboutMenuItem = new MenuItem("About"));
        menuBar.add(aboutMenu);

         //DEZE KAN NIET!!
         setMenuBar(menuBar);


        // assignments als parameter (expressie ) gebruiken
        // is niet mooi -> aparte assignments

        Button sendButton   = new Button("Send");
        Button resetButton  = new Button("reset");
        Button backButton   = new Button("Go Back");

        closeAction = new CloseAction(window);

        // vergeet niet je ActionListeners ook toe te voegen!
        sendButton.addActionListener(new SendAction());
        resetButton.addActionListener(new ResetAction());
        backButton.addActionListener(new GoBackAction());
        sendMenuItem.addActionListener(new SendAction());
        resetMenuItem.addActionListener(new ResetAction());
        exitMenuItem.addActionListener(new GoBackAction());
        aboutMenuItem.addActionListener(new AboutAction());

        Panel p = new Panel();
        p.add(sendButton);
        p.add(resetButton);
        p.add(backButton);

        // Gebruik geen "South" maar BorderLayout.SOUTH

        add(BorderLayout.SOUTH, p);

        fromField = new TextField(30);
        toField   = new TextField(30);
        // hum, dit wil je later vast een TextArea maken?
        messageField = new TextArea(20,40);
            
        Panel n = new Panel();
        n.setLayout(new FlowLayout());
        n.add(new Label("From:"));
        n.add(fromField);
        n.add(new Label("To:"));
        n.add(toField);
    
        // pack is hier niet zinvol omdat nog niet al je
        // componten zijn geplaatst
        // pack();
        
        // Ook hier weer BorderLayout.NORTH ipv "North"

        add(BorderLayout.NORTH, n);
        add(BorderLayout.CENTER, messageField);

        setBackground(Color.lightGray);

        // beter: laat de layout-manager zijn werk doen:
        // gebruik daarom pack() bij een Window.
        //    setBounds(100, 100, 400, 400);
        
        // Visible maken in een constructor is niet handig
        // en in dit geval ook niet meer mogelijk (panel).
        //setVisible(true);
    }

    // dit is ff een makkelijke methode om een Frame te maken
    public static Frame createFrame()
    {
        Frame frame = new Frame("E-mail composer");
        ComposeMail panel = new ComposeMail(frame);

        frame.addWindowListener(panel.getCloseAction());
        frame.add(panel);
        frame.pack();
        frame.setLocation(100,100);

        return frame;
    }

    //entry point, gewoon om ff te testen

    public CloseAction getCloseAction()
    {
        return closeAction;
    }

    // liever aparte ActionListeners dan gevalsonderscheid in 1 ActionListener

    class CloseAction extends WindowAdapter implements ActionListener
    {
        private Window window;

        public CloseAction(Window window)
        {
            super();
            this.window = window;
        }

        public void windowClosing(WindowEvent e)
        {
            window.dispose();
      }

        public void actionPerformed(ActionEvent event)
        {
            window.dispose();
        }
    }

    class SendAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            Frame newmaill = ComposeMail.createFrame();
            new SentMail();

        }
    }

    class ResetAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            messageField.setText("");
        }
    }

    class GoBackAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            Venster.newMail.dispose();
        }
    }

    class AboutAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
          new About();
        }
    }

}

Het specificeren van een menubar gaat goed,
maar setMenuBar(); kan hij niet vinden... :(

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
In principe is een MenuBar gewoon een Component dus je kan hem aan het Panel toevoegen op de gebruikelijke methode. Je wilt hem dan waarschijnlijk in het noorden hebben, maar helaas is die plek al bezet ;) . Je moet dan even een Panel nesten (of een complexere LayoutManager gebruiken).

Het is trouwens wel zo handig om de API documentatie erbij te houden ( http://java.sun.com/j2se/1.4/docs/api/ ) dan had je zelf kunnen vinden dat die methode setMenuBar in een Frame zit...

Overigens is dit inderdaad wel een nadeel van 'de Panel aanpak' en eigenlijk zou je dat ook iets beter moeten doen (met WindowHandles). Maar dat wordt een beetje te complex...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Zynth
  • Registratie: September 2001
  • Laatst online: 29-07 15:30
Ik ben er nog niet uitgekomen.
Ik heb het commando om de menubar te maken aangepast:
code:
1
2
//DEZE KAN NIET!!
         add(BorderLayout.NORTH, menuBar);

maar dit werkt ook niet.
owja; ik heb ff het panel dat eerst op north stond, op left gezet.

Verwijderd

daar heb je ook geen layout voor nodig, gewoon add(menuBar) doen...

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Hum dat zou toch moeten werken... Ik zal zo wel ff kijken of het hier werkt.

add(...) voegt een component trouwens op de default plek toe. Ik denk dat een layout positie hier dus toch wel handig is.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Hum, ik heb te lang niet meer in AWT gewerkt |:( .
MenuBar is helemaal geen component en je kan hem dus ook niet aan een Panel toevoegen. Je kan hem alleen maar instellen op een Frame (zelfs niet op een Dialog). In Swing is een menubar wel gewoon een component.

Ik heb het opgelost door een methode configure te maken die een Window configureert. Merk op dat nu ook de CloseAction niet meer publiek beschikbaar is, dat werkt wel aardig :) .

In Swing zou dit allemaal veel makkelijker en mooier kunnen, maar goed...

Hier is de code (kijk uit: ik heb niet al jouw code overgenomen, je moet hem dus ff mergen met jouw versie):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import java.awt.*;
import java.awt.event.*;

// Hoofdletter voor klassenaam
public class SendMailPanel extends Panel
{
    // Gebruik 1 declaratie per regel

    private TextField toField;
    private TextField fromField;
    private TextField messageField;

    private CloseAction closeAction;
    private MenuBar menuBar;

    public SendMailPanel(Window window)
    {
        super(new BorderLayout());

        closeAction = new CloseAction(window);

        MenuItem sendMenuItem   = new MenuItem("Send");
        MenuItem resetMenuItem  = new MenuItem("Reset");
        MenuItem exitMenuItem   = new MenuItem("Exit");
        MenuItem aboutMenuItem  = new MenuItem("About");

        sendMenuItem.addActionListener(new SendAction());
        resetMenuItem.addActionListener(new ResetAction());
        exitMenuItem.addActionListener(closeAction);
        aboutMenuItem.addActionListener(new AboutAction());

        menuBar = new MenuBar();
      Menu fileMenu   = new Menu("File");
          fileMenu.add(sendMenuItem);
        fileMenu.add(resetMenuItem);
        fileMenu.add(exitMenuItem);
      menuBar.add(fileMenu);
      Menu aboutMenu  = new Menu("Help");
        aboutMenu.add(aboutMenuItem);
      menuBar.add(aboutMenu);

        // assignments als parameter (expressie ) gebruiken 
        // is niet mooi -> aparte assignments

        Button sendButton   = new Button("Send");
        Button resetButton  = new Button("reset");
        Button backButton   = new Button("Go Back");

        // vergeet niet je ActionListeners ook toe te voegen!
        sendButton.addActionListener(new SendAction());
        resetButton.addActionListener(new ResetAction());
        backButton.addActionListener(new GoBackAction());

        Panel p = new Panel();
        p.add(sendButton);
        p.add(resetButton);
        p.add(backButton);

        // Gebruik geen "South" maar BorderLayout.SOUTH

        add(BorderLayout.SOUTH, p);

        fromField = new TextField(30);
        toField   = new TextField(30);
        // hum, dit wil je later vast een TextArea maken?
        messageField = new TextField(40);
            
        Panel n = new Panel();
        n.setLayout(new FlowLayout());
        n.add(new Label("From:"));
        n.add(fromField);
        n.add(new Label("To:"));
        n.add(toField);
    
        // pack is hier niet zinvol omdat nog niet al je
        // componten zijn geplaatst
        // pack();
        
        // Ook hier weer BorderLayout.NORTH ipv "North"

        add(BorderLayout.NORTH, n);
        add(BorderLayout.CENTER, messageField);

        setBackground(Color.lightGray);

        // beter: laat de layout-manager zijn werk doen:
        // gebruik daarom pack() bij een Window.
        //    setBounds(100, 100, 400, 400);
        
        // Visible maken in een constructor is niet handig
        // en in dit geval ook niet meer mogelijk (panel).
        //setVisible(true);
    }

    // dit is ff een makkelijke methode om een Frame te maken
    public static Frame createFrame()
    {
        Frame frame = new Frame("E-mail composer");

        SendMailPanel panel = new SendMailPanel(frame);
        panel.configure(frame);

        return frame;
    }

    //entry point, gewoon om ff te testen
    public static void main(String[] ps)
    {
        Frame frame = createFrame();
        frame.show();
    }
    
    public void configure(Window window)
    {
        window.addWindowListener(closeAction);
        window.add(this);

        if(window instanceof Frame)
        {
            Frame frame = (Frame) window;
            frame.setMenuBar(menuBar);
        }

        window.pack();
    }

    // liever aparte ActionListeners dan gevalsonderscheid in 1 ActionListener
    class CloseAction extends WindowAdapter implements ActionListener
    {
        private Window window;

        public CloseAction(Window window)
        {
            super();
            this.window = window;
        }

        public void windowClosing(WindowEvent e)
        {
            window.dispose();
      }

        public void actionPerformed(ActionEvent event)
        {
            window.dispose();
        }
    }

    class SendAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            // doe iets
        }
    }

    class ResetAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            // doe iets
        }
    }

    class GoBackAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            // doe iets
        }
    }

    class AboutAction implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
                // doe iets
        }
    }
}

Overigens zou je dit ook allemaal best zelf kunnen uitzoeken. Het is slechts een simpele combinatie van API documentatie leren lezen en kennis opdoen van Java.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1