JList

 

여러 개의 선택 항목 중에서 하나를 선택하기 위한 컴포넌트

 

리스트는 한 줄에 하나씩 선택 항목을 나타내며 화면은 스크롤이 가능하다.

 

사용자가 마우스로 선택한 항목을 더블 클릭하거나 엔터 키를 눌렀을 때 액션 이벤트가 발생한다.

 

생성자의 매개변수로 받을 ListModel은 디폴트일 경우 변경이 불가하여, 리스트에 항목을 추가하거나 삭제할 수 없다.

 

개별적으로 변경될 수 있는 리스트를 생성하기 위해서는 리스트 모델을 DefaultListModel의 인스턴스로 변경하여야 한다. 이는 setModel() 메소드를 호출함으로서 가능하다.

 

생성자

 JList() 

 빈 리스트를 생성한다.

 JList(Object[] items)

 매개변수로 받은 배열에 있는 값들을 가진 리스트를 생성한다.

 JList(ListModel list)

 지정된 리스트 모델을 사용하는 리스트를 생성한다.

 JList(Vector[] items) 

 벡터에 있는 값들을 가지고 선택항목을 생성한다.


- 선택 모드 : 디폴트값은 다중 구간 선택이다.

  • SINGLE_SELECTION : 단일 선택으로, 한 번에 하나의 항목만이 선택된다.

  • SINGLE_INTERVAL_SELECTION : 단일 구간 선택으로, 여러 개의 연속적인 항목들이 선택될 수 있다. 처음 클릭한 항목에서 쉬프트 키(Shift)를 누른 채로 원하는 범위의 항목(마지막 항목)까지 선택할 수 있다.

  • MULTIPLE_INTERVAL_SELECTION : 다중 구간 선택으로, 디폴트로 항목들이 자유롭게 선택될 수 있다. 연속적이지 않더라도 컨트롤 키(Ctrl)를 누른 채로 클릭하는 항목들은 모두 선택된다.


선택 모드를 변경하고 싶으면 setSelectionMode() 메소드를 호출하여 매개변수로 아래의 선택 모드 중 하나를 지정하면 된다.

  • ListSelectionModel.SINGLE_SELECTION

  • ListSelectionModel.SINGLE_INTERVAL_SELECTION

  • ListSelectionModel.MULTIPLE_INTERVAL_SELECTION

 

String[] listStr= { “김철수”, “김영희”, “김숙자”, “김자몽” };

JList myList= new JList(listStr); //생성자로 선택항목을 넘기는 것이 가장 일반적인 방법

myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);


 

이벤트 처리 : 리스트의 항목이 선택되면 리스트 선택 이벤트(ListSelectionEvent)가 발생한다. 해당 이벤트를 처리하려면 리스트 선택 리스너(ListSelectionListener) 인터페이스를 구현함으로써 해결할 수 있다. 리스트 선택 리스너에는 아래의 메소드 하나만 구현하면 된다.


@Override

public void valueChanged(ListSelectionEvent e) {

if (list.getSelectedIndex() == -1) { //getSelectedIndex() : 선택한 항목 인덱스 값 반환

//선택이 되지 않은 경우

} else { //선택되지 않은 경우 1을 반환한다.

//선택이 된 경우

}

 

if (list.getSelectedItem().equals(name) { //getSelectedItem() : 선택한 항목의 이름 반환

// 항목 이름이 name인 선택된 경우

} else {

// 선택되지 않았거나선택된 항목 이름이 name이 아닌 경우

}

 

if (list.getSelectedValue()!=null) { //getSelectedValue() : 선택된 항목(Object 타입반환

//하나라도 선택된 경우

} else {

//하나도 선택되지 않은 경우

}

}


 

경계선 만들기 : 다른 컴포넌트에도 있는 메소드이다. 숫자 1은 선의 굵기이다.

 

myList.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

 

화면에 표시되는 행 수 설정 : 스크롤 바 추가를 위해 행 수를 설정하는 것이 좋다.

 

listStr.setVisibleRowCount(10);

JScrollPane scrollPane = new JScrollPane(listStr);

scrollPane.setPreferredSize(new Dimension(300, 300)); //사이즈 설정

panel.add(scrollPane); //꼭 필요한 과정자주 까먹는 부분이니 주의바람.

 


리스트 항목 추가 : 디폴트 리스트 모델은 변경할 수 없기 때문에 새로운 DefaultListModel 인스턴스를 생성하여 생성자의 매개변수로 전달하여야 한다.

 

DefaultListModel model = new DefaultListModel();

model.addElement(“김철수”);

model.addElement(“김영희”);

model.addElement(“김숙자”);

model.addElement(“김자몽”);


JList myList = new JList(model); 


//또는


JList myList = new JList();

myList.setModel(model);

 

리스트 항목 제거

 

int index = 2;

model.remove(index); //위의 순서에서 인덱스가 2인 김숙자가 리스트에서 삭제된다.

 

-리스트 항목 삽입

 

model.insertElementAt("김커피", 1); //인덱스 1인 "김영희" 위치에 "김커피" 삽입된다.



- JList 예제

public class ListTest extends JFrame implements addListSelectionListener{

	//FIELDS
	private JLabel = new JLabel();
	private JTextField selectedList = new JTextField(10); //10글자까지 가능
	private JPanel listPanel = new JPanel();
	private JPanel labelPanel = new JPanel();
	private JList list;
	private JScrollPane scroll;
	private String[] names = {"김철수", "김영희", "김숙자", "김자몽"};

	//CONSTRUCTOR
	public ListTest() {
		setTitle("리스트 예제");
		setSize(500, 500);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //프레임을 껐을 때 완전한 종료
		
		list = new JList(names);

		//리스트의 경계선 설정
		list.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

		//리스트에 스크롤바 추가
		scroll = new JScrollPane(list);
		scroll.setPreferredSize(new Dimension(300, 300));

		//리스트의 단일 선택 모드 변경
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		//리스트 선택 리스너 등록
		list.addListSelectionListener(this);

		label.setText("선택된 항목 : ");
		selectedList.setEditable(false); //텍스트 필드 수정 불가상태로 바꾸기

		listPanel.add(scroll); //리스트를 패널에 추가
		labelPanel.add(label); //라벨을 패널에 추가
		labelPanel.add(selectedList); //텍스트 필드를 패널에 추가

		add(listPanel, BorderLayout.CENTER); //프레임 중앙에 리스트를 배치
		add(labelPanel, BorderLayout.SOUTH); //프레임 하단에 라벨과 텍스트 필드 배치

		setVisible(true);
	}

	//METHODS
	@Override
	public void valueChanged(ListSelectionEvent e) {
		// 선택된 이름 얻기
		String name = (String) list.getSelectedValue();

		selectedList.setText(name);
	}

	public static void main(String[] args) {
		ListText listFrame = new ListTest();
	}
}







 

 

JComponent 클래스

 

최상위 컨테이너를 제외하고는 거의 모든 컴포넌트가 JComponent를 상속받는다.

 

- JComponent 클래스에는 스윙 컴포넌트들이 공통적으로 가져야 하는 속성과 메소드가 포함되어 있다.

 

- JComponent 클래스는 ComponentContainer 클래스를 상속받는다.


- Component 클래스는 화면 그리기이벤트 처리 기능을 제공한다.


Container 클래스는 컴포넌트 추가 및 제거 기능레이아웃 기능을 제공한다


- 이 기능들은 스윙 컴포넌트들도 모두 사용할 수 있다.

 

 

 

컴포넌트의 외관 변경 메소드


메소드

설명

void setBorder(Border border)

Border getBorder()

컴포넌트의 경계를 설정하거나 반환한다.

void setForeground(Color color)

Color getForeground()

컴포넌트의 전경색을 설정하거나 반환한다.

void setBackground(Color color)

Color getBackground()

컴포넌트의 배경색을 설정하거나 반환한다.

void setFont(Font font)

Font getFont()

컴포넌트의 폰트를 설정하거나 반환한다.

void setCursor(Cursor cursor)

Cursor getCursor()

컴포넌트의 커서를 설정한다.

 

 

 

컴포넌트의 상태 변경 메소드


메소드

설명

void setToolTipText(String text)

툴팁에 표시되는 텍스트를 설정한다

툴팁 : 컴포넌트에 마우스를 두면 표시됨

void setName(String name)

String getName()

컴포넌트의 이름을 설정하거나 반환한다.

boolean isShowing()

컴포넌트가 화면에 표시되고 있으면 true, 표시되지 않으면 false를 반환한다.

void setEnabled(boolean enabled)

boolean isEnabled()

컴포넌트의 활성화 여부를 설정하고 반환한다.

void setVisible(boolean visible)

boolean isVisible()

컴포넌트를 화면에 표시할지를 설정하고 표시 여부를 반환한다.

 

 

 

공통 이벤트 처리 메소드


메소드

설명

void addMouseListener(MouseListener mouseListener)

마우스 리스너를 추가한다.

void removeMouseListener(MouseListener mouseListener)

마우스 리스너를 제거한다.

void addActionListener(ActionListener actionListener)

액션 리스너를 추가한다.

void removeActionListener(ActionListener actionListener)

액션 리스너를 제거한다.

...

각 리스너마다 메소드가 addXXXX(), removeXXXX() 형태로 존재한다.




▶ 컴포넌트 그리기 메소드


메소드

설명

void repaint()

void repaint(int x1, int y1, int x2, int y2)

컴포넌트의 일부나 전체를 다시 그리라고 요청한다.

void revalidate()

컨테이너 안의 컴포넌트를 다시 배치하라고 요청한다.

void paintComponent(Grpahics g)

컴포넌트를 그린다. 만약 사용자 맞춤형 컴포넌트에서는 이 메소드를 오버라이딩(재정의)하여서 그림을 그린다.



 

컨테이너에 컴포넌트 추가 및 제거 메소드


메소드

설명

Component add(Component component)

컴포넌트를 컨테이너에 추가한다.

void remove(Component component)

컨테이너에서 컴포넌트를 삭제한다.

 void removeAll()

컨테이너의 모든 컴포넌트를 삭제한다.

Container getParent()

컴포넌트가 추가된 컨테이너를 반환한다.




▶ 레이아웃 메소드

 

메소드

설명

int getWidth()

int getHeight()

해당 컴포넌트의 너비와 높이를 픽셀 단위로 반환한다.

Dimension getSize()

해당 컴포넌트의 크기를 픽셀 단위로 반환한다.

int getX()

int getY()

부모 컨테이너를 기준으로 컴포넌트의 상대적인 x좌표, y좌표를 반환한다.

Point getLocation()

부모 컨테이너 안에서의 상대적인 위치를 반환한다.

Point getLocationOnScreen()

모니터 화면에서의 절대 위치를 반환한다.

void setLocation(int x, int y)

void setLocation(Point point)

부모 컨테이너 안에서의 컴포넌트의 좌표를 지정하며, 배치 관리자가 없는 경우에만 유효하다.

void setBounds(int x, int y, int width, int height)

부모 컨테이너 안에서의 컴포넌트의 위치와 크기를 설정한다. 배치 관리자가 없는 경우에만 유효하다.



 

크기와 위치 정보 얻는 메소드


메소드

설명

void setPreferredSize(Dimension dimen)

void setMaximumSize(Dimension dimen)

void setMinimunSize(Dimension dimen)

컴포넌트의 크기, 최소 크기, 최대 크기를 설정한다.

void setAlignmentX(float x)

void setAlignmentY(float y)

컨테이너 안에서의 컴포넌트들의 정렬을 지정한다.

void setLayout(LayoutManager)

LayoutManager getLayout()

배치 관리자를 설정하거나 반환한다.








 추상 클래스


 - 객체를 직접 생성할 수 있는 클래스를 실체 클래스라고 하는 반면, 이 실체 클래스들의 공통적인 속성(필드와 메소드)만 뽑아내어 선언한 클래스를 추상 클래스라 한다.


 - 추상 클래스는 new 연산자를 사용하여 객체를 생성할 수 없다.

 

 - 추상 클래스와 실체 클래스는 상속의 관계에 놓여있다.


 - 추상 클래스가 부모이고 실체 클래스가 자식으로 구현되며, 실체 클래스는 추상 클래스에 있는 속성 외에 추가적인 속성을 가질 수 있다.


 - 추상 클래스는 새로운 실체 클래스를 위한 부모 클래스의 용도로만 사용된다.



 추상 클래스의 장점


 - 실체 클래스들의 필드와 메소드를 통일하여 실체 클래스 작성 시 시간을 절약할 수 있다.



▶ 추상 클래스의 선언



public abstract class 클래스명 {

//필드

//생성자

//메소드

}




 추상 메소드와 오버라이딩(Overriding)


 - 추상 메소드란 메소드의 선언부만 있고 메소드 실행 내용인 중괄호 {}가 없는 메소드를  말한다. 끝에는 항상 세미콜론이 있다.


 - 추상 메소드는 추상 클래스에서만 선언할 수 있다.


 - 메소드 실행 내용인 중괄호 블록은 추상 메소드를 상속받은 실체 메소드에서 직접 작성한다.


 - 반드시 자식 클래스는 추상 메소드를 재정의(Overriding)해서 실행 내용을 작성해야 한다.


 - 즉, 추상 클래스를 설계할 때, 하위(자식) 클래스가 반드시 실행해야 하는 메소드를 추상 메소드로 선언하면 된다.



public abstract class Car{

//필드

public int speed;

public String owner;


//생성자

public Car(String owner) {

this.owner = owner;

}


//메소드

public abstract void accelerate(int speed);

public abstract void whatKind();


public void driving() { //모든 자식 객체가 실행하는 메소드

System.out.println("운전 중");

}


}




public class SportCar extends Car{

//필드

int speed;


//생성자

public SportCar(String owner, int speed) {

super(owner);


this.speed = speed;

}


//메소드

@Override

public void accelerate(int speed) {

if(speed > 0) {

this.speed += ( 2 * speed );

}

}


@Override

public void whatKind() {

System.out.println("스포츠카입니다.");

}

}




public class Truck extends Car {

//필드

int speed;


//생성자

public SportCar(String owner, int speed) {

super(owner);


this.speed = speed;

}


//메소드

@Override

public void accelerate(int speed) {

if(speed > 0) {

this.speed += speed;

}

}


@Override

public void whatKind() {

System.out.println("트럭입니다.");

}

}




public class CarTest { //실행 클래스, 객체의 속성을 정의하는 클래스와는 별도로 생성하는 것이 좋다.

public static void main(String[] args) {

SportCar sportCar = new SportCar();

Truck truck = new Truck();


sportCar.whatKind();

truck.whatKind();


sportCar.driving();

truck.driving();


//변수의 자동 타입 변환

Car car = null;

car = new SportCar();

car.whatKind();

car = new Truck();

car.whatKind();

}

}



 

 

* 상속


- 자바에서 상속이란 부모 클래스의 멤버를 자식 클래스에게 물려주는 행위이다.


- 프로그램에서는 자식 클래스가 부모 클래스를 선택하며 클래스명 뒤에 “extends 부모 클래스명를 기술하여 사용한다.


- , 다중 상속은 허용하지 않는다.

 

class 자식클래스명 extends 부모클래스1, 부모클래스2 --> 절대 X

 

- 다른 패키지의 클래스를 상속할 경우 패키지명.클래스명을 import해야한다.

상속의 장점


- 상속은 이미 개발된 클래스를 재사용하여 새로운 클래스를 만들기 때문에 코드의 중복을 줄여준다.


- 상속을 이용하여 클래스의 수정을 최소화할 수 있다. , 유지 보수 시간을 최소화한다.


package sec.example;

 

public class A {

int field1;

 

void method1() { ... }    

}

 

public class B extends A { //A를 상속함

String field2;

 

void method2() { ... }

}



 

상속 가능 범위


- 부모 클래스에서 private 접근 제한을 갖는 멤버들(필드와 메소드)은 상속 대상에서 제외된다.


- 부모 클래스와 자식 클래스가 서로 다른 패키지일 때 부모 클래스의 default 접근 제한을 갖는 멤버들도 상속 대상에서 제외된다.


- 그 외에 상속한 클래스의 필드와 메소드는 자식 클래스에서 자유롭게 사용할 수 있다.


B b = new B();

//A로부터 물려받은 필드와 메소드

b.field1 = 10;

b.method1();

 

//B가 추가한 필드와 메소드

b.field2 = "홍길동“;

b.method2();



 

* 부모 생성자의 호출


- 자식 객체를 생성하면, 부모 객체가 먼저 생성되고 그 다음에 자식 객체가 생성된다. 마치, 부모 없는 자식이 없는 것처럼 말이다.


- 부모 생성자는 자식 생성자의 맨 첫줄에서 super() 키워드를 통해 호출된다. 생성자가 명시적으로 선언되지 않았다면 컴파일러는 디폴트 생성자에 super(); 키워드를 맨 앞에 추가하여 생성해 낸다. 여기서 super(매개변수); 는 부모 생성자 역할을 한다.


- super의 매개변수는 부모 생성자의 매개변수의 형태와 동일해야한다.

 

 

* 메소드의 재정의(Overriding)


- 어떤 메소드는 상속받은 자식 클래스에서 사용하기에 부적합할 수도 있다. 이 문제를 해결하고자 상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용할 수 있다. , 자식 클래스에서 부모 클래스의 메소드와 동일한 메소드를 재정의하는 것을 말한다.


- 재정의할 메소드 위에는 @Override 키워드가 있어야 한다.


- 메소드가 오버라이딩되면 부모 객체의 메소드는 숨겨지기 때문에 자식 객체에서 메소드를 호출하면 오버라이딩된 자식 객체가 호출된다.


- 그러나 간혹, 숨겨진 부모 객체의 메소드를 사용해야 할 때가 있다면, super 키워드를 이용하여 호출할 수 있다.


 super.부모메소드();



- 메소드 오버라이딩 규칙

  • 부모의 메소드와 동일한 구조(리턴 타입, 메소드 이름, 매개 변수 리스트)를 가져야 한다.
  • 접근 제한을 더욱 강하게 오버라이딩 할 수 없다.
  • (상속된 부모 객체의 메소드가 default일 때 private로 바꿀 수 없으며, public으로는 가능하다.)
  • 새로운 예외(Exception)throws 할 수 없다.

 


final 클래스와 final 메소드


- 상속할 수 없는 final 클래스 : 클래스 선언 시 아래와 같이 class 앞에 final 키워드를 붙이게 되면 이 클래스는 최종적인 클래스이므로 상속할 수 없는 클래스가 된다. , final 클래스는 부모 클래스가 될 수 없다.


public final class 클래스명 { ... }



- 오버라이딩(Overriding)할 수 없는 final 메소드 : 메소드를 선언할 때 final 키워드를 붙이게 되면 이 메소드는 최종적인 메소드가 되므로 오버라이딩할 수 없는 메소드가 된다. , 부모 클래스에서 상속해서 자식 클래스를 선언할 때 부모 클래스에 선언된 final 메소드는 자식 클래스에서 재정의할 수 없다.


public final 리턴타입 메소드(매개변수) { ... } //해당 메소드 재정의 불가




* protected 접근 제한자


- 부모 클래스의 멤버가 protected 접근 제한자를 가질 경우 자식 클래스는 다른 패키지라도 부모 객체의 필드, 생성자, 메소드를 사용할 수 있다.


- 생성자의 경우, 부모 객체를 new 연산자로 생성하는 것이 아니라 자식 클래스의 생성자에서 super(); 키워드를 통해서 호출할 수 있다.

 

 

* 타입 변환과 다형성


- 다형성은 하나의 타입에 여러 객체를 대입하여 이용할 수 있는 성질을 말한다. 이러한 다형성을 위해 자바는 자식 클래스에서 부모 클래스로 자동 타입 변환하는 것을 허용한다. , 부모 타입에는 모든 자식 객체가 대입될 수 있다.

 

만약 Car 클래스를 상속하는 SportCar 클래스가 있다면,


SportCar mySportCar = new SportCar();

Car myCar = mySportCar; //자동 타입 변환


mySportCar 변수와 myCar 변수는 타입만 다를 뿐 동일한 객체(SportCar)를 참조한다.


- 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체 외에 상속받는 자식 객체까지도 매개값으로 사용할 수 있다.


- , 부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근할 수 있다. , 변수는 자식 객체를 참조하더라도 해당 변수로 접근 가능한 멤버는 부모 클래스의 멤버로 제한된다.


- 그러나 메소드가 자식 클래스에서 오버라이딩 되었다면 부모 타입으로 자동 타입 변환되어도 오버라이딩된 메소드가 호출된다.


- 바로 위의 부모 클래스가 아니더라도 상속 계층에서 상위 타입이라면 하위 타입이 자동 타입변환 된다.

- 강제 타입 변환(Casting) : 자식 타입이 부모 타입으로 자동 변환한 후, 다시 자식타입으로 변환할 때 강제 타입 변환을 해야 한다. 즉, 부모 타입에 부모 객체가 아닌 자식 객체가 있는 경우에 가능하다.

 

자식클래스 변수 = (자식클래스) 부모클래스;

 

 

* 객체 타입 확인


- 강제 타입 변환은 자식 타입이 부모 타입으로 변환되어 있는 상태에서만 가능하므로 부모 타입의 변수가 부모 객체를 참조할 경우 자식 타입으로 변환할 수 없다.


- instanceof : 위의 문제점을 해결하고자 어떤 객체가 어떤 클래스의 인스턴스(객체)인지 확인하는데 사용되는 연산자이다. 


boolean result = 좌항(객체) instanceof 우항(타입);



- 해당 타입이면 true, 아니면 false를 리턴한다.


// Child extends Parent

// Child -> Parent (자동타입변환)

// Parent -> Child (캐스팅)

 

public void method(Parent parent) {

Child child1 = new Child();

Parent parent = child1;


//parent 변수가 참조하는 객체는 Child 클래스의 인스턴스(객체)인가?

if(parent instanceof Child) {

    Child child = (Child) parent

    }

}




 

+ Recent posts