14. 자바 JMenu 사용법
- JMenuBar
이곳에 메뉴항목을 추가할 수 있다.
- JMenu
메뉴바에 추가가능한 메뉴 항목
- JMenuItem
메뉴의 아이템을 구현하기 위한 클래스
예제소스
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
|
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class test extends JFrame {
test(){
super("swing test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300,200);
//메뉴바 생성
JMenuBar mb = new JMenuBar();
//메뉴항목 추가
JMenu jm = new JMenu("메뉴1");
//메뉴의 아이템 추가
jm.add(new JMenuItem("빨강"));
jm.add(new JMenuItem("파랑"));
jm.addSeparator(); //메뉴 아이템의 구분선 생성
jm.add(new JMenuItem("노랑"));
//메뉴바에 메뉴 추가
mb.add(jm);
mb.add(new JMenu("초록"));
//프레임에 메뉴바 붙이기
setJMenuBar(mb);
setVisible(true);
}
public static void main(String[] args) {
new test();
}
}
|
cs |
Action 이벤트 달기
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
|
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class test extends JFrame {
JLabel jl = new JLabel("test");
test(){
super("swing test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300,200);
//메뉴바 생성
JMenuBar mb = new JMenuBar();
//메뉴 생성
JMenu jm = new JMenu("메뉴1");
//메뉴 아이템 생성
JMenuItem mi1 = new JMenuItem("빨강");
JMenuItem mi2 = new JMenuItem("파랑");
JMenuItem mi3 = new JMenuItem("노랑");
//이벤트 리스너 달기
mi1.addActionListener(new MenuActionListener());
mi2.addActionListener(new MenuActionListener());
mi3.addActionListener(new MenuActionListener());
//메뉴에 아이템 추가
jm.add(mi1);
jm.addSeparator(); //메뉴 아이템의 구분선 생성
jm.add(mi2);
jm.add(mi3);
//메뉴바에 메뉴 추가
mb.add(jm);
mb.add(new JMenu("메뉴2"));
//프레임에 메뉴바 붙이기
setJMenuBar(mb);
//라벨 설정
jl.setSize(200, 200);
jl.setFont(new Font("Revie",Font.ITALIC,30));
add(jl);
setVisible(true);
}
// 메뉴 클릭시 사용할 리스너 클래스 작성
class MenuActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
//선택된 메뉴아이템의 문자열 가져오기
String s = e.getActionCommand();
if(s == "빨강") {
jl.setForeground(Color.red);
}else if(s == "파랑") {
jl.setForeground(Color.blue);
}else if(s == "노랑") {
jl.setForeground(Color.yellow);
}
}
}
public static void main(String[] args) {
new test();
}
}
|
아마... static 전역 사용 대신... 값을 읽어 와서 하는게 더 효율 적인거 같다.
그리고 계속하여 메뉴가 묻혀 버리는 경우가 있었다.
계속 고민하다 보니 super.paint(g)를 사용 하지 않았던 것이 원인이었다.
겨우 해결...
이 외에 메뉴 표시 정렬 (과제 1 : 써본 적 없음)을 하려고 하여 보니..... 답이 스택 오버 플로우에도 없고.... 있어도 메뉴를 상속 받아서 아예 재구현을 하는 수준이라서..... 메뉴 대신 버튼을 새로 짜야 하나 생각하고 있었는데......
독에 아이콘을 넣는 기능 (과제 2 : 써본 적 없음)이 있다고 한다. 더 찾아 봐야 겠다.
어쨌든 JMenu도 완전히 구현된 기능은 아닌거 같고.... 싫으면 있을지도 모를 자바 신버전을 써야 할 거 같은데....
하다가 영 안 되면 나중에 재상속 구현 (과제 3 : 써본 적 없음 )을 생각해 봐야겠다.
어쨌든 밑에는 새로 찾은 참고 자료이다.
▶ JMenuBar
- 메뉴는 공간을 절약함과 동시에 사용자에게 여러 가지 옵션 중에서 하나를 선택하게 하는 컴포넌트이다.
- 다른 컴포넌트와 달리 컨테이너 안에 배치되지 않는다. 즉, 항상 맨 위에 고정적인 자리를 가진다.
- 메뉴바는 프레임에만 부착될 수 있다. 패널은 부착불가.
- 메뉴는 메뉴바에 나타나거나 팝업 메뉴로만 나타난다.
- 메뉴바에 메뉴를 나열하고, 메뉴바에 나열된 메뉴들에서 각 메뉴 항목을 가진다.
- 메뉴 항목에는 텍스트뿐만 아니라 이미지도 올 수 있고 체크 박스도 올 수 있다. 또한, 폰트나 색상도 변경 가능하다.
- 팝업 메뉴란 사용자가 팝업이 가능한 컴포넌트 위에서 마우스 우클릭을 할 때 등장한다.
- 메뉴는 JAbstractButton 클래스를 상속하고 있으므로 일종의 버튼이라 보면 된다. 따라서 누르면 이벤트가 발생한다.
- 메뉴바는 JMenuBar 객체, 메뉴는 JMenu 객체, 메뉴 항목은 JMenuItem 객체로 만들어진다.
- 팝업메뉴는 JPopupMenu라는 객체를, 체크박스 메뉴항목은 JCheckboxMenuItem 객체에 의해 표현된다.
- Simple Example
...
JFrame frame = new JFrame(“메뉴바 예제”);
JMenuBar menuBar; //메뉴바 선언
JMenu menu; //메뉴 선언
JMenuItem menuItem; //메뉴 항목 선언
menuBar = new JMenuBar(); //메뉴바 초기화
menu = new JMenu(“메뉴1”);
menuBar.add(menu);
menuItem = new JMenuItem(“메뉴항목1”); //메뉴항목 선언
//menuItem = new JMenuItem(“메뉴항목1”, KeyEvent.VK_T); ->키보드 단축키 설정 가능
menu.add(menuItem); //메뉴에 메뉴항목 추가
frame.setJmenuBar(menuBar); //프레임에 메뉴바 설정
...
- 각 메뉴 항목마다 단축키를 설정하려면 setMenuShortCut 메소드를 불러오면 된다.
- 이벤트 처리 : 메뉴항목(JMenuItem)을 눌렀을 때 발생하는 이벤트를 처리하기 위해 ActionListener 인터페이스를 구현한다.
- 키보드와의 관계 : 메뉴는 기억키(menmontcs)와 가속키(accelerators)의 두 가지 종류의 키보드 선택을 지원한다. 기억키는 모든 사용자를 위한 것이고, 가속키는 고급 사용자를 위한 것이라고 생각하면 된다.
- 기억키는 setMnemonic() 메소드를, 가속키는 setAccelerator() 메소드를 사용한다.
- 기억키 : 키보드를 사용하여 이미 표시되어 있는 메뉴 계층을 둘러보는데 이용된다. 주로 메뉴에 단축키를 설정하여 Alt를 누르면 첫 번째 메뉴가 선택되게 한다.
menuItem.setMnemonic(KeyEvent.VK_T);
- 가속키 : 메뉴 계층 구조를 통하지 않고 직접 메뉴 항목을 선택할 수 있다. 즉, 메뉴 항목이 선택되는 키들의 조합이다. 예를 들어 Alt + 1을 눌렀을 때 Alt 단축키를 가진 메뉴의 서브 메뉴 항목의 첫 번째를 선택하게 된다. 단말 메뉴 항목만이 가속키를 가질 수 있다.
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_t, ActionEvent_ALT_MASK));
- 예제
public class MenuTest extends JFrame implements ActionListener, ItemListener {
//FIELDS
private JMenuBar menuBar = new JMenuBar();
private JMenu firstMenu, secondMenu, submenu;
private JMenuItem menuItem1, menuItem2;
private JMenuItem subMenuItem1, subMenuItem2;
private ButtonGroup group = new ButtonGroup();
private JRadioButtonMenuItem rbMenuItem1, rbMenuItem2;
private JCheckBoxMenuItem cbMenuItem1, cbMenuItem2;
MenuTest() {
//첫번째 메뉴 초기화
firstMenu = new JMenu("first menu");
firstMenu.setMnemonic(KeyEvent.VK_F); //단축키 설정
menuBar.add(firstMenu);
//메뉴 항목 생성
menuItem1 = new JMenuItem("menu item 1", KeyEvent.VK_1);
menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.ALT_MASK));
menuItem1.addActionListener(this); //리스너 설정해야 이벤트 처리 가능함
firstMenu.add(menuItem1); //메뉴항목을 첫번째 메뉴에 등록
ImageIcon icon = new ImageIcon("example_icon.png");
menuItem2 = new JMenuItem("menu item 2", icon); //이미지 등록
menuItem2.addActionListener(this);
menu.add(menuItem2);
//라디오 버튼 메뉴 항목 생성
firstMenu.addSeparator(); // 구분자 생성
rbMenuItem1 = new JRadioButtonMenuItem("radio button item 1");
rbMenuItem1.setSelected(true); //선택 되어있도록 설정
group.add(rbMenuItem1); //버튼 그룹에 추가
firstMenu.add(rbMenuItem1); //그룹에 추가하는 것과 메뉴에 추가하는 것은 별도이다.
rbMenuItem2 = new JRadioButtonMenuItem("radio button item 2");
group.add(rbMenuItem2);
firstMenu.add(rbMenuItem2);
//체크 박스 메뉴 항목 생성
firstMenu.addSeparator();
cbMenuItem1 = new JCheckBoxMenuItem("check box item 1");
cbMenuItem1.addItemListener(this); //체크박스는 아이템 이벤트가 발생함 (액션 이벤트와는 별도 처리)
firstMenu.add(cbMenuItem1);
cbMenuItem2 = new JCheckBoxMenuItem("check box item 2");
cbMenuItem2.addItemListener(this);
firstMenu.add(cbMenuItem2);
//서브 메뉴 생성
submenu.addSeparator();
submenu = new JMenu("sub menu");
submenu.setMnemonic(KeyEvent.VK_S); //단축키 설정
subMenuItem1 = new JMenuItem("sub menu item 1");
subMenuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
submenu.add(subMenuItem1);
subMenuItem2 = new JMenuItem("sub menu item 2");
subMenuItem2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
submenu.add(subMenuItem2);
menu.add(submenu);
//두번째 메뉴 초기화
secondMenu = new JMenu("second menu");
secondMenu.addActionListener(this);
menu.setMnemonic(KeyEvent.VK_S);
menuBar.add(menu);
//프레임에 메뉴바 추가하기
setJMenuBar(menuBar);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == menuItem1) {
System.out.println("This is the menu item 1.");
}else if (e.getSource() == menuItem2) {
System.out.println("This is the menu item 2.");
}
}
@Override
public void itemStatedChanged(ItemEvent e) {
if (e.getSource() == cbMenuItem1) {
System.out.println("check box item 1");
else (e.getSource() == cbMenuItem2) {
System.out.println("check box item 2");
}
}
public static void main(String[] args) {
MenuTest frame = new MenuTest();
f.setSize(500, 500);
f.setVisible(true);
}
}
여기서 팁을 또하나 주자면.... 배열을 사용하면 중복된 값을 엄청 줄일 수 있다. !!!