[GUI] Swing 12월 20일

포키·2022년 12월 20일
1

국비과정

목록 보기
39/73
  • requestFocus() : 포커스 두기
  • selectAll :

Event

JMouseListener

Component

JMenuItem

  • 메뉴, 메뉴바, 메뉴아이템으로 구성
  • JFrame의 ContentPane의 최상단에 위치 (배치 변경 불가)

JMenu

JRadioButtonMenuItem

JCheckBoxMenuItem

JMenuBar

JPopupMenu

JToolBar

관련 메서드

setActionCommand(String cmd)

setAccelerator(KeyStroke keys)

KeyStroke : 키조합 의미 클래스

	KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)

setMnemonic(char c)

니모닉 mnemonic : 연상기호, 버튼과 일대일 대응하는 기호(char)

코드 MouseEventEx

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();
	}
}

코드 MenuEx

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();
	}
}

코드 FakeChat

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();
	}
}
profile
welcome

0개의 댓글