- LookAndFeel 이란
- mnemonic 이란
requestFocus()
: 포커스 두기selectAll
:
KeyStroke : 키조합 의미 클래스
KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)
니모닉 mnemonic : 연상기호, 버튼과 일대일 대응하는 기호(char)
package kr.ac.green;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.BevelBorder;
public class MouseEventEx extends JFrame {
private JLabel lblLeft;
private JLabel lblRight;
public MouseEventEx() {
init();
setDisplay();
addListeners();
showFrame();
}
private void init() {
lblLeft = new JLabel();
lblLeft.setOpaque(true);
lblLeft.setBackground(Color.WHITE);
lblRight = new JLabel("", JLabel.CENTER);
setLayout(new GridLayout(1, 2));
add(lblLeft);
add(lblRight);
}
private void setDisplay() {
}
private void addListeners() {
// MouseListener도 메서드 많음 -> MouseAdapter 사용
// Toolkit 이용하면 커서 모양 변경 가능 (createCustomCursor())
MouseListener mListener = new MouseAdapter() {
// override 단축키 : alt + shift + s -> v
// 실행 순서 : Pressed -> Released -> Clicked
// Clicked <- 누르고 떼는 동작이 모두 이뤄진 후 실행
@Override
public void mouseClicked(MouseEvent e) {
// 주로 더블클릭 등에 사용
System.out.println("Clicked");
if(e.getClickCount() == 2) {
lblRight.setText(e.getX() + "," + e.getY());
}
// 더블클릭으로 인지되는 시간 간격 = 속도는 Swing이 아니라 운영체제에서 설정
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("Pressed");
// getSource(), getStateChange(), getButton()
/*
* BUTTON1 : 좌
* BUTTON2 : 휠
* BUTTON3 : 우
*/
int button = e.getButton();
/*
String buttonNum = "button";
if (button == MouseEvent.BUTTON1) {
button += 1;
} else if (button == MouseEvent.BUTTON2) {
button += 2;
} else if (button == MouseEvent.BUTTON3) {
button += 3;
}
System.out.println(buttonNum);
*/
if (button == MouseEvent.BUTTON1) {
// 마우스 클릭 유지
lblLeft.setBorder(new BevelBorder(BevelBorder.LOWERED));
}
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("Released");
// 마우스 클릭 중단
lblLeft.setBorder(new BevelBorder(BevelBorder.RAISED));
}
@Override
public void mouseEntered(MouseEvent e) {
// 마우스 커서가 컴포넌트에 올라갈 때
lblLeft.setBackground(Color.YELLOW);
lblLeft.setCursor(new Cursor(Cursor.HAND_CURSOR));
Toolkit kit = Toolkit.getDefaultToolkit();
// public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
// hotSpot <- 클릭되는 포인트
lblLeft.setCursor(kit.createCustomCursor(kit.getImage("chick.png"), new Point(0, 0), "chick"));
}
@Override
public void mouseExited(MouseEvent e) {
// 마우스 커서가 컴포넌트에서 벗어날 때
lblLeft.setBackground(Color.WHITE);
}
};
lblLeft.addMouseListener(mListener);
}
private void showFrame() {
setTitle("MouseEvent ex");
setSize(600, 300);
setLocation(100, 0);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new MouseEventEx();
}
}
package kr.ac.green;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
// Component <- Container : 상속관계, Container = Component + "컴포넌트 포함 기능"
// JMenuItem <- JMenu : 상속관계, JMenu = JMenuItem + "포함된 JMenuItem을 보여주는 기능"
// JMenu = "열림 기능이 포함된 JMenuItem"
public class MenuEx extends JFrame {
private JMenuBar mBar;
private JMenu mFile;
private JMenuItem miOpen;
private JMenuItem miSave;
private JMenuItem miExit;
private JMenu mOption;
private JMenuItem miOptionA;
private JMenuItem miOptionB;
private JMenu mSettings;
private JRadioButtonMenuItem mrbtnKor;
private JRadioButtonMenuItem mrbtnEng;
private JCheckBoxMenuItem mchLineWrap;
private JCheckBoxMenuItem mchAutoHidden;
private JButton btnExit;
private JLabel lblMain;
private JPopupMenu pMenu;
private JMenuItem miPopupOpen;
private JMenuItem miPopupSave;
private JToolBar tBar;
// ToolBar는 상, 하, 좌, 우가 비워진 BorderLayout에만 사용한다.
// 사용자가 마우스를 통해 임의로 상, 하, 좌, 우의 공간에 놓을 수 있기 때문!
private JButton btnOpen;
private JButton btnSave;
private JButton btnEnd;
public MenuEx() {
init();
setDisplay();
addListeners();
showFrame();
}
private void init() {
// 컴포넌트들을 주어진 LookAndFeel(UI 형식? 테마?)로 바꿔줌
// 컴포넌트 생성 전 가장 먼저 사용해야 함!
/*
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
e.printStackTrace();
}
*/
mBar = new JMenuBar();
mFile = new JMenu("File");
// 니모닉 mnemonic : 연상기호, 버튼과 일대일 대응하는 기호(char)
miOpen = new JMenuItem("Open", 'o');
miOpen.setIcon(new ImageIcon("open.png"));
miOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
// '|' <- 논리합 (2진수)
// '&' <- 논리곱 (2진수) (비트 조합 확인용 : 비트 값을 두 개 합쳐놓고, 비트 값으로 나눠보면서 그 비트값이 들어가있는지 확인?)
miSave = new JMenuItem("Save");
miSave.setIcon(new ImageIcon("save.png"));
miSave.setMnemonic('s');
miSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.ALT_DOWN_MASK));
// ctrl + x
// 키조합을 나타내는 객체 'KeyStroke'
miExit = new JMenuItem("Exit");
KeyStroke keys = KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK);
// getKeyStroke(int keyCode, int modifiers)
// 일반 키보드의 물리적 키 keycode, 섞어쓰는 키 modifiers(ctrl 등)
// keycode -> 물리적 키보드의 키에 가상 키보드의 키를 매핑.
miExit.setAccelerator(keys);
// setAccelerator(KeyStroke keys) : 단축키 설정
// 참고 - 줄 쳐진 메서드 = "Deprecated"
// Deprecated : 문제 생길 여지가 있어 앞으로 사용을 지양하려는 메서드 (호환성 문제로 못 없앰)
miExit.setIcon(new ImageIcon("exit.png"));
mOption = new JMenu("Option");
miOptionA = new JMenuItem("option-A");
miOptionB = new JMenuItem("option-B");
mSettings = new JMenu("Settings");
mrbtnKor = new JRadioButtonMenuItem("Korean", true);
mrbtnEng = new JRadioButtonMenuItem("English");
ButtonGroup group = new ButtonGroup();
group.add(mrbtnKor);
group.add(mrbtnEng);
mchLineWrap = new JCheckBoxMenuItem("Auto Hidden");
mchAutoHidden = new JCheckBoxMenuItem("Auto Hidden");
mSettings.add(mrbtnKor);
mSettings.add(mrbtnEng);
mSettings.addSeparator();
mSettings.add(mchLineWrap);
mSettings.add(mchAutoHidden);
btnExit = new JButton("exit");
btnExit.setActionCommand("byebye");
btnExit.setMnemonic('y');
// 버튼에도 니모닉 설정 가능, alt와 함께 눌러야 함
lblMain = new JLabel("start", JLabel.CENTER);
lblMain.setFont(new Font(Font.SERIF, Font.BOLD, 50));
pMenu = new JPopupMenu();
miPopupOpen = new JMenuItem("Open");
miPopupOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.ALT_DOWN_MASK));
// 단축키 설정은 가능하지만, Popup이 열려있을 때만 동작함
// 일반적으로 Popup 메뉴는 즐겨찾기처럼 이미 있는 기능을 빠르게 볼 수 있게 모아둔 것
// 보통은 같은 기능을 하는 일반 메뉴아이템 & Popup 메뉴아이템의 단축키를 같게 설정한다!
miPopupSave = new JMenuItem("Save");
pMenu.add(miPopupOpen);
pMenu.add(miPopupSave);
tBar = new JToolBar();
//tBar.setFloatable(false);
btnOpen = new JButton(new ImageIcon("open.png"));
btnSave = new JButton(new ImageIcon("save.png"));
btnEnd = new JButton(new ImageIcon("exit.png"));
btnEnd.setActionCommand("byebye");
tBar.add(btnOpen);
tBar.add(btnSave);
tBar.addSeparator(new Dimension(100, 0));
// 툴바의 separator는 두께 조절도 가능 (Dimension)
tBar.add(btnEnd);
}
private void setDisplay() {
mOption.add(miOptionA);
mOption.add(miOptionB);
mFile.add(miOpen);
mFile.add(miSave);
mFile.addSeparator();
mFile.add(mOption);
mFile.addSeparator();
mFile.add(miExit);
mBar.add(mFile);
mBar.add(mSettings);
setJMenuBar(mBar);
JPanel pnlMain = new JPanel(new BorderLayout());
pnlMain.add(lblMain, BorderLayout.CENTER);
pnlMain.add(btnExit, BorderLayout.SOUTH);
add(pnlMain, BorderLayout.CENTER);
add(tBar, BorderLayout.NORTH);
}
private void addListeners() {
ActionListener aListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
Object src = ae.getSource();
String cmd = ae.getActionCommand();
if(cmd.equals("byebye")) {
// getActionCommand() : 이벤트를 발생시킨 명령어를 가져옴.
// 기본 명령어는 컴포넌트의 텍스트이나, setActionCommand(String cmd) 메서드를 통해 변경 가능
// ActionCommand를 잘 사용하여 행위별로 명령어를 통일하고, 리스너 안의 조건문을 간략하게 표시 가능
lblMain.setText(ae.getActionCommand());
closeWindow();
} else {
JMenuItem mi = (JMenuItem) src;
if(mi == miOpen || mi == miPopupOpen) {
JFileChooser fc = new JFileChooser(".");
// JFileChooser(String 참조위치(경로))
fc.showOpenDialog(MenuEx.this);
// public int showOpenDialog(Component parent)
// 현재는 참조위치가 현재 디렉토리인 JFileChooser의 OpenDialog를 보여줌
}
lblMain.setText(mi.getText());
}
}
};
miOpen.addActionListener(aListener);
miSave.addActionListener(aListener);
miExit.addActionListener(aListener);
btnExit.addActionListener(aListener);
miPopupOpen.addActionListener(aListener);
btnEnd.addActionListener(aListener);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
closeWindow();
}
});
// 팝업 메뉴를 보여주는 시점도 운영체제가 결정함
// : 운영체제별로 팝업 메뉴를 보여주는 시점이 마우스 누를 때 or 마우스 뗄 때로 갈릴 수 있음
// 자바의 장점 - 운영체제 free -> 둘 다 만들어둬야 함
lblMain.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent me) {
showPopup(me);
}
@Override
public void mouseReleased(MouseEvent me) {
showPopup(me);
}
});
}
private void showPopup(MouseEvent me) {
// 조건은 우클릭 + (운영체제에서 정함) 실행시점 (Pressed or Released)
// isPopupTrigger() : 운영체제에 맞는 Popup 조건을 확인하는 메서드
// Returns whether or not this mouse event is the popup menutrigger event for the platform.
if(me.isPopupTrigger()) {
pMenu.show(lblMain, me.getX(), me.getY());
// void show(Component invoker, int x, int y)
}
}
private void closeWindow() {
int choice = JOptionPane.showConfirmDialog(
this,
"종료하시겠습니까?",
"종료",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE
);
if(choice == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
private void showFrame() {
setTitle("Menu ex");
setSize(500, 400);
setLocation(100, 0);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new MenuEx();
}
}
package kr.ac.green;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class FakeChat extends JFrame {
private JTextArea taOutput;
private JTextField tfInput;
public FakeChat() {
taOutput = new JTextArea();
taOutput.setEditable(false);
tfInput = new JTextField(30);
add(new JScrollPane(taOutput), BorderLayout.CENTER);
add(tfInput, BorderLayout.SOUTH);
tfInput.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
String text = ((JTextField)ae.getSource()).getText();
// taOutput.setText(taOutput.getText() + text + "\n");
taOutput.append(text + "\n");
// JTextComponent <- append()로 text에 추가 가능
// public void append(String str)
// Appends the given text to the end of the document. Does nothing ifthe model is null or the string is null or empty.
}
});
setTitle("Fake Chat");
setSize(500, 400);
setLocation(100, 0);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new FakeChat();
}
}