2020.11.28 TIL

How to migrate to intellij from netbeans?

https://www.javatpoint.com/intellij-idea-migrating-from-netbeans

https://www.tutorialspoint.com/intellij_idea/intellij_idea_migrating_from_netbeans.htm

How to add external libraries in IntelliJ?

https://goddaehee.tistory.com/243

How to user password fields

https://docs.oracle.com/javase/tutorial/uiswing/components/passwordfield.html

Swing Layout

https://kamang-it.tistory.com/entry/Swing-04Layout%EB%B0%B0%EC%B9%98%EA%B4%80%EB%A6%AC%EC%9E%90

button

문제점1. SignUp 생성자는 매개변수로 Window를 전달받는데, SignUp 버튼의 ActionListener는 LogIn클래스의 signBtn.addActionListener메서드 안에 정의된 로컬 클래스이다. 따라서 this 키워드로 생성자를 호출하면 내부 클래스인 ActionListener가 참조된다.

java.lang.Object
	java.awt.Component
		java.awt.Container
			java.awt.Window
				java.awt.Frame
					javax.swing.JFrame

JFrame은 Window 객체를 상속한다. 따라서 JFrame을 상속하는 LogIn객체를 직접 넘겨줄 방법을 찾아야한다.

 signBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                SignUp signUp = new SignUp(LogIn, txtID);
              	SignUp signUp = new SignUp(this, txtID);
                signUp.setVisible(true);
            }
        });

위와 같은 방법으로는 LogIn객체를 직접 참조할수가 없다.

해결1. JFrame 객체를 생성해서 SignUp생성자로 전달

public class LogIn {
	private JFrame frame;
  private JButton signBtn;
  
	public LogIn() {					
    frame = new JFrame();		// 생성자에서 JFrame 객체 생성
		signBtn = new JButton();
    
    signBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              	// SignUp 생성자에 JFrame 객체를 전달
              	SignUp signUp = new SignUp(frame, txtID);
                signUp.setVisible(true);
            }
        });
  }
  
}

this 를 넣으면 ActionListener가 전달되고, LogIn을 넣으면 아직 생성되기 전이라서 호출이 불가능하다. 따라서 extends JFrame을 하지않고, 클래스변수로 Frame을 선언하고 생성자에서 미리 생성하면 버튼 액션 리스너로 Frame을 전달할 수 있다.

해결2. 중첩 클래스에서 바깥 클래스 참조 얻기

public class LogIn extends JFrame { // JFrame을 상속하는 클래스
	private JFrame frame;
  private JButton signBtn;
  
	public LogIn() {					
    frame = new JFrame();		// 생성자에서 frame 인스턴스 생성
		signBtn = new JButton();  
  
  signBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              	// SignUp 생성자에 외부 객체의 참조값을 전달
                SignUp signUp = new SignUp(LogIn.this, txtID);
                signUp.setVisible(true);
            }
        });
  }
}
	

굳이 frame을 생성하고 전달하는 방식으로 구현하지 않고, class LogIn extends JFrame으로 선언하여도 된다. 중첩 클래스의 내부 클래스에서 this키워드로 객체를 참조하면 ActionListener가 참조된다. 하지만 외부클래스인 LogIn을 참조하기 위해서는 LogIn.this로 참조하면 된다.

https://stackoverflow.com/questions/20252727/is-not-an-enclosing-class-java